-
Notifications
You must be signed in to change notification settings - Fork 812
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
BinaryLogClient will always continue even if one of the EventListeners errors out on an event #15
Comments
I have made some improvements to my fork that I think are going to simplify things: The way I have things now:
The idea is that it should be possible to write new subclasses of My next steps:
|
Howdy, Can I ask why didn't you go with registering (just an example) FailureIntolerantDelegatingEventListener which calls disconnect() on the client when some event listener (among registered) throws an exception, like so:
public class FailureIntolerantDelegatingEventListener
implements BinaryLogClient.EventListener {
private final BinaryLogClient binaryLogClient;
private final List<EventListener> eventListeners =
new LinkedList<EventListener>();
public FailureIntolerantDelegatingEventListener(
BinaryLogClient binaryLogClient) {
this.binaryLogClient = binaryLogClient;
}
public void registerEventListener(EventListener eventListener) {
eventListeners.add(eventListener);
}
@Override
public void onEvent(Event event) {
for (EventListener eventListener : eventListeners) {
try {
eventListener.onEvent(event);
} catch (Exception e) {
binaryLogClient.disconnect();
break; // do not notify remaining event listeners
}
}
}
}
// and then somewhere in the code:
...
BinaryLogClient binaryLogClient = ...
FailureIntolerantDelegatingEventListener delegatingEventListener =
new FailureIntolerantDelegatingEventListener(binaryLogClient);
delegatingEventListener.registerEventListener(<event listener>);
delegatingEventListener.registerEventListener(<another event listener>);
...
binaryLogClient.registerEventListener(delegatingEventListener);
binaryLogClient.connect();
... If, for some reason, you don't like the idea of EventListener being aware of BinaryLogClient and you really want BinaryLogClient itself to take care of any failures, then how about issue-15-proposed-change? It's basically few lines change which would allow to override ("in-place") notification strategy used by BinaryLogClient. As for the "BinaryLogClient should only have one EventListener and one LifecycleListener", personally I'd rather not do that. Even if we set aside backward compatibility (as stable (API-wise) version is not in Maven Central yet) I would argue that it's too restrictive (=frustrating) (especially when you want to register (temporary) some tracing / monitoring listeners which do not care (or even know) about other registered ones (like in tests)). Moreover, no one is forcing to use binaryLogClient.registerEventListener more than once if you absolutely don't want to :). Please let me know your thoughts on this. |
A handful of reasons. First of all, well, I didn't think of it, for starters :-P. Second: design-wise, I thought that Third: implicitly swallowing the For example, in my project I'm trying to record the history of changes to a table that is subject to frequent UPDATE statements. This means for each event, I have to:
If the event listener for example fails to insert into the target, it really makes no sense to continue. Even worse, if a target insert failure is later followed by a success, then I've put the target into an erroneous state. So "swallow by default" strikes me as a dangerous default, in that it makes it easier for careless people to implement listeners like this one incorrectly. (Note that I count myself among the careless.) It's also more complex to reason about, because just like I can write an It's your code, however, so your call. I could certainly live with this proposal for now.
I don't like it for this reason: such Though in this case thankfully the
To my eye, a subclass that overrode But again, your code, your call.
That was my first idea, but I changed my mind pretty quickly. The patch for #16 ended up not having this. Summary: there are three proposals on the table that AFAIK can all be made to work:
|
You're probably right. I also tend to agree on "too many responsibilities" part. Let me think it through. |
Well, in the meantime, I've implemented a version of your |
I'm attempting to use the library for a project at my job, and I'm running into a problem because the
BinaryLogClient
will continue dispatching events to everyEventListener
, even if one (or all) of the listeners throws an exception on a previous event.I have a proposed refactoring in order to make failure handling more flexible. The core ideas (ignoring backward compatibility for a moment, and imagining an ideal world) are:
BinaryLogClient
should only have oneEventListener
and oneLifecycleListener
.EventListener
throws an exception, theBinaryLogClient
should abort and disconnect immediately.BroadcastEventListener
(and aBroadcastLifecycleListener
) that handles the registration/unregistration logic, dispatches to the registered listeners, and "swallows" the child listeners' exceptions if desired (the same behavior as the current code).I have started a fork exploring these ideas (sacundim@8edbda1). In order not to break existing code that uses the library, I've modified the ideas described above in this way:
BinaryLogClient
should continue to behave exactly the same way as it does now.AbstractBinaryLogClient
and moved most of the original logic there.I still have three issues I'd like to work through, though:
BinaryLogClient.LifecycleListener
has methods that take aBinaryLogClient
argument. In my modified code as of now, this needs to be changed toAbstractBinaryLogClient
, which means that existingLifecycleListener
implementations will no longer compile.I'd appreciate to have your input into this matter.
The text was updated successfully, but these errors were encountered: