package com.zendesk.maxwell.producer; import com.codahale.metrics.MetricRegistry; import com.zendesk.maxwell.metrics.MaxwellMetrics; import com.zendesk.maxwell.MaxwellContext; import com.zendesk.maxwell.replication.Position; import com.zendesk.maxwell.row.RowMap; public abstract class AbstractAsyncProducer extends AbstractProducer { public final static String succeededMessageCountName = MetricRegistry.name(MaxwellMetrics.getMetricsPrefix(), "messages", "succeeded"); public final static String succeededMessageMeterName = MetricRegistry.name(MaxwellMetrics.getMetricsPrefix(), "messages", "succeeded", "meter"); public final static String failedMessageCountName = MetricRegistry.name(MaxwellMetrics.getMetricsPrefix(), "messages", "failed"); public final static String failedMessageMeterName = MetricRegistry.name(MaxwellMetrics.getMetricsPrefix(), "messages", "failed", "meter"); public class CallbackCompleter { private InflightMessageList inflightMessages; private final MaxwellContext context; private final Position position; private final boolean isTXCommit; private final long sendTimeMS; private Long completeTimeMS; public CallbackCompleter(InflightMessageList inflightMessages, Position position, boolean isTXCommit, MaxwellContext context) { this.inflightMessages = inflightMessages; this.context = context; this.position = position; this.isTXCommit = isTXCommit; this.sendTimeMS = System.currentTimeMillis(); } public void markCompleted() { if(isTXCommit) { Position newPosition = inflightMessages.completeMessage(position); if(newPosition != null) { context.setPosition(newPosition); } } completeTimeMS = System.currentTimeMillis(); } public Long timeToSendMS() { if ( completeTimeMS == null ) return null; return completeTimeMS - sendTimeMS; } } private InflightMessageList inflightMessages; public AbstractAsyncProducer(MaxwellContext context) { super(context); this.inflightMessages = new InflightMessageList(); } public abstract void sendAsync(RowMap r, CallbackCompleter cc) throws Exception; @Override public final void push(RowMap r) throws Exception { Position position = r.getPosition(); // Rows that do not get sent to a target will be automatically marked as complete. // We will attempt to commit a checkpoint up to the current row. if(!r.shouldOutput(outputConfig)) { inflightMessages.addMessage(position); Position completed = inflightMessages.completeMessage(position); if(completed != null) { context.setPosition(completed); } return; } if(r.isTXCommit()) { inflightMessages.addMessage(position); } CallbackCompleter cc = new CallbackCompleter(inflightMessages, position, r.isTXCommit(), context); sendAsync(r, cc); } }