package org.sef4j.core.helpers.senders;
import java.util.List;
import java.util.Queue;
import org.sef4j.core.helpers.senders.BulkAsyncSender.IAsyncDisruptorErrorHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* default implementation of IAsyncDisruptorErrorHandler<T>, to be used within BulkAsyncSender<T>
*/
public class DefaultAsyncDisrupterErrorHandler<T> implements IAsyncDisruptorErrorHandler<T> {
private static final Logger LOG = LoggerFactory.getLogger(DefaultAsyncDisrupterErrorHandler.class);
protected int currentRetryIndex = 0;
protected int maxRetryCount = 3;
protected int maxQueueBulksCount = 100;
protected int delayOnError = 60; // 1 minute
// ------------------------------------------------------------------------
public DefaultAsyncDisrupterErrorHandler() {
}
// ------------------------------------------------------------------------
@Override
public void onSendEventsOK(List<T> events) {
this.currentRetryIndex = 0;
}
@Override
public int onSendEventsFailed(List<T> events, RuntimeException ex,
List<List<T>> retryPrependBulkEvents,
List<List<T>> retryAppendBulkEvents) {
currentRetryIndex++;
String retryInfo = (1 + currentRetryIndex) + "/" + maxRetryCount;
if (currentRetryIndex < maxRetryCount) {
// re-put (or re-prepend) requests in current Bulk request to send!
// TODO ... retryable/not-retryable => should analyse exception...
int skipCount = 0;
// TODO skip somes events?
retryPrependBulkEvents.add(events);
if (skipCount != 0) {
LOG.error("Failed bulk request, retry " + retryInfo
+ ": skipping " + skipCount + " old request(s)"
+ " .. reschedule, no rethrow", ex);
} else {
LOG.warn("Failed bulk request, retry " + retryInfo
+ " .. reschedule, no rethrow, ex:" + ex.getMessage());
}
} else {
// giving up ... current messages
// keep incremented currentRetryIndex ?
String msg = "Retry failed " + retryInfo
+ ": skipping " + events.size() + " bulk request(s) !";
if (currentRetryIndex > maxRetryCount) {
// do not print with exception stack trace again and again
LOG.error(msg + " ex=" + ex.getMessage());
} else {
LOG.error(msg, ex);
}
}
return delayOnError; // + bulkAsyncSender.getFlushPeriod();
}
@Override
public void onQueued(Queue<List<T>> queue, List<T> events) {
while (queue.size() > maxQueueBulksCount) { // avoid out of memory, at least! (retain max= 100 bulks of ~20 requests)
queue.poll();
}
}
}