-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rewindable event handler separation #440
Rewindable event handler separation #440
Conversation
…able Using `EventHandler::setSequenceCallback` with the newly added concept of Rewinding in the `BatchEventProcessor` is not going to go well as an `EventHandler` can change the sequence before a rewind. Non-rewindable `EventHandler` implementations are not able to throw a `RewindableException`.
private final Sequence sequence = new Sequence(Sequencer.INITIAL_CURSOR_VALUE); | ||
private BatchRewindStrategy batchRewindStrategy = new SimpleBatchRewindStrategy(); | ||
private int retriesAttempted = 0; | ||
private final boolean rewindable; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than a boolean
, could we have behaviour?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking something like adding an private inner interface:
private final interface RewindBehaviour
{
long onRewindableException(RewindableException e);
}
and then there could be two private methods:
private long beKindRewind(final RewindableException e)
{
if (this.batchRewindStrategy.handleRewindException(e, ++retriesAttempted) == REWIND)
{
return startOfBatchSequence;
}
else
{
retriesAttempted = 0;
throw e;
}
}
private long rewindNotAllowed(final RewindableException e)
{
throw new RuntimeException("Rewindable Exception thrown from a non-rewindable event handler", e);
}
Constructors would then take this::beKindRewind
in place of true
and this::rewindNotAllowed
in place of false? (one catch here is that they might not be referencable in this()
calls, so eh?).
This would save continuously checking an if
that will never change; on the other hand it does possibly make navigation slightly harder?
Also, this really only works because retriesAttempted
appears to be instance scoped? I'm assuming this is so we persist failures across calls until we get a success, but it's not entirely clear to me?
|
||
/** | ||
* Construct a {@link EventProcessor} that will automatically track the progress by updating its sequence when | ||
* the {@link EventHandler#onEvent(Object, long, boolean)} method returns. | ||
* | ||
* <p>This constructor will not support rewinding batches. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about 'The created BEP will not support batch rewind". The constructor is just a constructor
* Construct a {@link EventProcessor} that will automatically track the progress by updating its sequence when | ||
* the {@link EventHandler#onEvent(Object, long, boolean)} method returns. | ||
* | ||
* <p>This constructor will support rewinding batches. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same same - the constructor isn't supporting anything!
*/ | ||
package com.lmax.disruptor; | ||
|
||
interface BaseEventHandler<T> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gentle preference for EventHandlerBase over BaseEventHandler, which sounds like an EventHandler that someone has done something unpleasant to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I sort of hate that we've got three constructors on BEP; if it weren't such a ballache I'd be suggesting some named factory methods instead.
I agree with Simon's suggestion of behaviour rather than boolean.
Don't think any of my comments are showstoppers.
Extending And if we're going that path, it isn't an |
I also questioned this offline - my understanding of the reasoning here is that we have no way of allowing the regular handlers to throw an arbitrary exception but not a Something like this would work in theory:
but that would require catching and wrapping every |
e5ea360
to
6f98f61
Compare
On the topic of exceptions and use of Throwable: I think it's justified here as it's a specific exception we want to raise in a certain circumstance. There's probably some major refactoring I'd like to make in a future major release to make For now I think it's a fair trade off as the |
…y the rewind supporting build method
…ndler-separation2 # Conflicts: # src/main/java/com/lmax/disruptor/BatchEventProcessor.java # src/main/java/com/lmax/disruptor/EventHandler.java # Manually fixed up: # src/main/java/com/lmax/disruptor/EventHandlerBase.java
992576a
to
ea61e82
Compare
d248ea9
to
63d5af7
Compare
An overly keen find & replace made more changes than necessary while changing from direct BatchEventProcessor construction to using the builder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Wonder if we can move the retriesAttempted
variable off the handler into the retry strategy as a next-step refactor?
Man this interface is appalling for reviewing. |
This should give us type-safe rewindable and non-rewindable
EventHandler
implementations.Non-rewindable implementations will not be able to throw
RewindableException
but will be able to implementEventHandler::setSequenceCallback
and the opposite for rewindable implementations.This will fix #437