Hi Stephanie,
For the situation that you mention, there is a couple of other options that may work. The solutions mentioned below will be much more efficient that the full implementation of clear that I mentioned in the previous email.
1) Just swallow the exception/error that you get from the protocol. This works if the client that you are using to send with can throw an exception quickly if the connection is unavailable. This is not always possible, e.g. using TCP/IP can result in long delays before a send will fail, especially if the remote endpoint goes away without the local machine seeing a fin or rst packet.
@Override
public void onEvent(ValueEvent event, long sequence, boolean endOfBatch) throws Exception
{
try
{
send(event);
}
catch (ProtocolException e)
{
// handle exception
}
}
Within handle exception, either log a message or record a counter*, but don't re-throw the exception. This will allow the EventHandler to skip over events until the connection becomes available again.
* In high performance systems, which may dealing with exceptions that could occur at very frequent intervals, e.g. once per message I tend to avoid logging and instead use a counter that I can monitor external with something like JMX. Most logging systems tend to be fairly inefficient and logging large number of exceptions can actually cause the system to fall into an even worse state.
2) The event handler could detect the error then set a use a sequence number to discard old events. The Cursored interface is implemented by the RingBuffer class, so on construction you would need to inject and instance of the RingBuffer into the EventHandler.
E.g.
public class SkippingEventHandler implements EventHandler<ValueEvent>
{
private final Cursored cursored;
private long skipOverSequence = -1;
public SkippingEventHandler(Cursored cursored)
{
this.cursored = cursored;
}
@Override
public void onEvent(ValueEvent event, long sequence, boolean endOfBatch) throws Exception
{
if (sequence <= skipOverSequence)
{
return;
}
try
{
send(event);
}
catch (ProtocolException e)
{
sequence = cursored.getCursor();
// handle exception
}
}
}
3) If you wanted to manage the skipping over of events from a separate thread (I'm sure which thread you are calling clear() from in your current implementation) then you could add a volatile field. You would call RingBuffer.getCursor() and pass it into the skipEvent method.
public class SkippingEventHandler implements EventHandler<ValueEvent>
{
private volatile long skipOverSequence = -1;
@Override
public void onEvent(ValueEvent event, long sequence, boolean endOfBatch) throws Exception
{
if (sequence <= skipOverSequence)
{
return;
}
try
{
send(event);
}
catch (ProtocolException e)
{
sequence = cursored.getCursor();
// handle exception
}
}
public void skipEvents(long sequenceToSkipOver)
{
this.skipOverSequence = sequenceToSkipOver;
}
}
Mike.