import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
+import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
@RequiredArgsConstructor
public class ApplicationRecordHandler implements RecordHandler<String, String>
{
private final AdderResults results;
+ private final Optional<Duration> throttle;
+ private final String id;
private final Map<Integer, AdderBusinessLogic> state = new HashMap<>();
+ private final Map<Integer, Long> next = new HashMap<>();
@Override
String user = record.key();
String message = record.value();
+ if (record.offset() < next.get(partition))
+ {
+ log.warn(
+ "{}- Dropping duplicate message: offset={} < next={}",
+ id,
+ record.offset(),
+ next.get(partition));
+ return;
+ }
+
if (message.equals("CALCULATE"))
{
AdderResult result = state.get(partition).calculate(user);
- log.info("New result for {}: {}", user, result);
+ log.info("{} - New result for {}: {}", id, user, result);
results.addResults(partition, user, result);
- return;
}
+ else
+ {
+ state.get(partition).addToSum(user, Integer.parseInt(message));
+ }
+
+ next.put(partition, record.offset() + 1);
- state.get(partition).addToSum(user, Integer.parseInt(message));
+ if (throttle.isPresent())
+ {
+ try
+ {
+ Thread.sleep(throttle.get().toMillis());
+ }
+ catch (InterruptedException e)
+ {
+ log.warn("{} - Intrerrupted while throttling: {}", id, e);
+ }
+ }
}
- protected void addPartition(Integer partition, Map<String, AdderResult> state)
+ protected void addPartition(Integer partition, Map<String, AdderResult> state, Long offset)
{
this.state.put(partition, new AdderBusinessLogic(state));
+ this.next.put(partition, offset);
}
- protected Map<String, AdderResult> removePartition(Integer partition)
+ protected ApplicationState removePartition(Integer partition)
{
- return this.state.remove(partition).getState();
+ ApplicationState state = getState(partition);
+ this.next.remove(partition);
+ this.state.remove(partition);
+ return state;
}
return state;
}
- public AdderBusinessLogic getState(Integer partition)
+ public ApplicationState getState(Integer partition)
{
- return state.get(partition);
+ return
+ new ApplicationState(
+ this.next.get(partition),
+ this.state.get(partition).getState());
}
}