Duration.ofSeconds(5), Duration.ofMinutes(60), new Distribution(Subscriber.MAX_ACK_DEADLINE_SECONDS + 1), flowController, new LinkedList<MessageDispatcher.OutstandingMessageBatch>(),
@Override public void onSuccess(AckReply reply) { LinkedBlockingQueue<String> destination; switch (reply) { case ACK: destination = pendingAcks; // Record the latency rounded to the next closest integer. ackLatencyDistribution.record( Ints.saturatedCast( (long) Math.ceil((clock.millisTime() - receivedTimeMillis) / 1000D))); break; case NACK: destination = pendingNacks; break; default: throw new IllegalArgumentException(String.format("AckReply: %s not supported", reply)); } destination.add(ackId); forget(); } }
/** Compute the ideal deadline, set subsequent modacks to this deadline, and return it. */ @InternalApi int computeDeadlineSeconds() { long secLong = ackLatencyDistribution.getNthPercentile(PERCENTILE_FOR_ACK_DEADLINE_UPDATES); int sec = Ints.saturatedCast(secLong); // Use Ints.constrainToRange when we get guava 21. if (sec < Subscriber.MIN_ACK_DEADLINE_SECONDS) { sec = Subscriber.MIN_ACK_DEADLINE_SECONDS; } else if (sec > Subscriber.MAX_ACK_DEADLINE_SECONDS) { sec = Subscriber.MAX_ACK_DEADLINE_SECONDS; } return sec; }
@Test public void testOverflowMaxValue() { // Record value greater than maxValue-1 is OK. We record maxValue-1 instead. Distribution dist = new Distribution(10); dist.record(10); assertThat(dist.getPercentile(100)).isEqualTo(9); }
@Deprecated public long getNthPercentile(double percentile) { return getPercentile(percentile); }
private Distribution of(Integer... values) { int max = Collections.max(Arrays.asList(values)); Distribution dist = new Distribution(max + 1); for (int value : values) { dist.record(value); } return dist; } }
@Deprecated public long getNthPercentile(double percentile) { return getPercentile(percentile); }
@Test public void testPercentile() { // These tests come from examples in https://en.wikipedia.org/wiki/Percentile#The_nearest-rank_method Distribution dist; dist = of(15, 20, 35, 40, 50); assertThat(dist.getPercentile(5)).isEqualTo(15); assertThat(dist.getPercentile(30)).isEqualTo(20); assertThat(dist.getPercentile(40)).isEqualTo(20); assertThat(dist.getPercentile(50)).isEqualTo(35); assertThat(dist.getPercentile(100)).isEqualTo(50); dist = of(3, 6, 7, 8, 8, 10, 13, 15, 16, 20); assertThat(dist.getPercentile(25)).isEqualTo(7); assertThat(dist.getPercentile(50)).isEqualTo(8); assertThat(dist.getPercentile(75)).isEqualTo(15); assertThat(dist.getPercentile(100)).isEqualTo(20); dist = of(3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20); assertThat(dist.getPercentile(25)).isEqualTo(7); assertThat(dist.getPercentile(50)).isEqualTo(9); assertThat(dist.getPercentile(75)).isEqualTo(15); assertThat(dist.getPercentile(100)).isEqualTo(20); }
@Test(expected = IllegalArgumentException.class) public void testZeroMaxValue() { new Distribution(0); }
ackLatencyDistribution.record(60);
@Test(expected = IllegalArgumentException.class) public void testNegativeMaxValue() { new Distribution(-1); }