-
Notifications
You must be signed in to change notification settings - Fork 0
test whether it is possible to consume before the producer gets an ack #97
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| import io.quarkus.logging.Log; | ||
| import io.spoud.config.SynthClientConfig; | ||
| import io.spoud.kafka.PartitionRebalancer; | ||
| import io.vertx.core.impl.ConcurrentHashSet; | ||
| import jakarta.enterprise.context.ApplicationScoped; | ||
| import org.eclipse.microprofile.config.inject.ConfigProperty; | ||
|
|
||
|
|
@@ -89,7 +90,12 @@ public void recordProducedFailure() { | |
| recordsFailedCounter.increment(); | ||
| } | ||
|
|
||
| synchronized public void recordLatency(String topic, int partition, long latencyMs, String fromRack) { | ||
| synchronized public void recordLatency(String topic, int partition, long latencyMs, String fromRack, long offset) { | ||
| if (fromRack.equals(config.rack()) && !ackedOffsets.contains(new AckedMessage(offset, partition))) { | ||
| Log.warnf("Consumed message %d:%d before receiving an ACK! This means that Ack latency could be higher than E2E latency!", partition, offset); | ||
| } else { | ||
| ackedOffsets.remove(new AckedMessage(offset, partition)); | ||
| } | ||
| Log.debugv("Latency for partition {0}: {1}ms", partition, latencyMs); | ||
| if (partitionRebalancer.isInitialRefreshPending()) { | ||
| Log.info("Ignoring latencies as the initial partition assignment is not done yet"); | ||
|
|
@@ -132,7 +138,12 @@ public Collection<WrappedDistributionSummary> getE2ELatencies() { | |
| return e2eLatencies.values(); | ||
| } | ||
|
|
||
| public void recordAckLatency(String topic, int partition, Duration between) { | ||
| public record AckedMessage(long offset, int partition) { | ||
| } | ||
| private final Set<AckedMessage> ackedOffsets = new ConcurrentHashSet<>(); | ||
|
|
||
| public void recordAckLatency(String topic, int partition, Duration between, long offset) { | ||
| ackedOffsets.add(new AckedMessage(offset, partition)); | ||
| Log.debugv("Ack latency for partition {0}: {1}ms", partition, between.toMillis()); | ||
| if (partitionRebalancer.isInitialRefreshPending()) { | ||
| Log.info("Ignoring ack latency as the initial partition assignment is not done yet"); | ||
|
|
@@ -192,8 +203,8 @@ private WrappedDistributionSummary genE2eSummary(String topic, int partition, St | |
| .tag(TAG_FROM_RACK, fromRack) | ||
| .tag(TAG_BROKER_RACK, brokerRack) | ||
| .description("End-to-end latency of the synthetic client") | ||
| .minimumExpectedValue(1.0) | ||
| .maximumExpectedValue(10_000.0) | ||
| .minimumExpectedValue(config.expectedMinLatency()) | ||
| .maximumExpectedValue(config.expectedMaxLatency()) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this makes sense. might be influencing the P9s to a certain extend. This change should survive. |
||
| .publishPercentiles(0.5, 0.8, 0.9, 0.95, 0.99) | ||
| .publishPercentileHistogram(config.publishHistogramBuckets()) | ||
| .distributionStatisticExpiry(config.samplingTimeWindow()) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -78,7 +78,6 @@ public void recreateProducer() { | |
| } | ||
|
|
||
| public void send(Long key, String value) { | ||
| Instant send = Instant.now(); | ||
| var record = new ProducerRecord<>(config.topic(), null, timeService.currentTimeMillis(), key, value); | ||
| record.headers().add(HEADER_RACK, config.rack().getBytes()); | ||
| record.headers().add(HEADER_ADVERTISED_LISTENER, config.advertisedListener().orElse("").getBytes()); | ||
|
|
@@ -87,9 +86,10 @@ var record = new ProducerRecord<>(config.topic(), null, timeService.currentTimeM | |
| Log.error("Failed to send message", exception); | ||
| metricService.recordProducedFailure(); | ||
| } else { | ||
| Instant ack = Instant.now(); | ||
| lastMessage.set(ack); | ||
| metricService.recordAckLatency(metadata.topic(), metadata.partition(), Duration.between(send, ack)); | ||
| Instant ackTime = Instant.ofEpochMilli(timeService.currentTimeMillis()); | ||
| Instant sendTime = Instant.ofEpochMilli(metadata.timestamp()); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. metadata.timestamp is now set by broker? this would add another time source into the mix, no?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think metadata.timestamp is the timestamp we give during production, no?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, depending on the topic configuration log.message.timestamp.type or message.timestamp.type. |
||
| lastMessage.set(ackTime); | ||
| metricService.recordAckLatency(metadata.topic(), metadata.partition(), Duration.between(sendTime, ackTime), metadata.offset()); | ||
| metricService.recordProducedSuccess(); | ||
| } | ||
| }); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here we cause a potential memory leak as we never remove the item that was missing here if it's added to the list later on. list will grow forever.