private Context(Timer timer, Clock clock) { this.timer = timer; this.clock = clock; this.startTime = clock.getTick(); }
@Override public long getTick() { return delegate.getTick(); }
/** * Creates a new {@link Meter}. * * @param clock the clock to use for the meter ticks */ public Meter(Clock clock) { this.clock = clock; this.startTime = this.clock.getTick(); this.lastTick = new AtomicLong(startTime); }
private long getTick() { for ( ;; ) { final long oldTick = lastTick.get(); final long tick = (clock.getTick() - startTick) * COLLISION_BUFFER; // ensure the tick is strictly incrementing even if there are duplicate ticks final long newTick = tick - oldTick > 0L ? tick : oldTick + 1L; if (lastTick.compareAndSet(oldTick, newTick)) { return newTick; } } }
private long getTick() { for ( ;; ) { final long oldTick = lastTick.get(); final long tick = clock.getTick() * COLLISION_BUFFER; // ensure the tick is strictly incrementing even if there are duplicate ticks final long newTick = tick - oldTick > 0 ? tick : oldTick + 1; if (lastTick.compareAndSet(oldTick, newTick)) { return newTick; } } }
private boolean shouldLoad() { for ( ;; ) { final long time = clock.getTick(); final long current = reloadAt.get(); if (current > time) { return false; } if (reloadAt.compareAndSet(current, time + timeoutNS)) { return true; } } } }
/** * Times and records the duration of event. * * @param event a {@link Runnable} whose {@link Runnable#run()} method implements a process * whose duration should be timed */ public void time(Runnable event) { final long startTime = clock.getTick(); try { event.run(); } finally { update(clock.getTick() - startTime); } }
/** * Creates a new {@link SlidingTimeWindowReservoir} with the given clock and window of time. * * @param window the window of time * @param windowUnit the unit of {@code window} * @param clock the {@link Clock} to use */ public SlidingTimeWindowReservoir(long window, TimeUnit windowUnit, Clock clock) { this.clock = clock; this.measurements = new ConcurrentSkipListMap<>(); this.window = windowUnit.toNanos(window) * COLLISION_BUFFER; this.lastTick = new AtomicLong(clock.getTick() * COLLISION_BUFFER); this.count = new AtomicLong(); }
/** * Creates a new {@link SlidingTimeWindowArrayReservoir} with the given clock and window of time. * * @param window the window of time * @param windowUnit the unit of {@code window} * @param clock the {@link Clock} to use */ public SlidingTimeWindowArrayReservoir(long window, TimeUnit windowUnit, Clock clock) { this.startTick = clock.getTick(); this.clock = clock; this.measurements = new ChunkedAssociativeLongArray(); this.window = windowUnit.toNanos(window) * COLLISION_BUFFER; this.lastTick = new AtomicLong((clock.getTick() - startTick) * COLLISION_BUFFER); this.count = new AtomicLong(); }
/** * Times and records the duration of event. Should not throw exceptions, for that use the * {@link #time(Callable)} method. * * @param event a {@link Supplier} whose {@link Supplier#get()} method implements a process * whose duration should be timed * @param <T> the type of the value returned by {@code event} * @return the value returned by {@code event} */ public <T> T timeSupplier(Supplier<T> event) { final long startTime = clock.getTick(); try { return event.get(); } finally { update(clock.getTick() - startTime); } }
/** * Times and records the duration of event. * * @param event a {@link Callable} whose {@link Callable#call()} method implements a process * whose duration should be timed * @param <T> the type of the value returned by {@code event} * @return the value returned by {@code event} * @throws Exception if {@code event} throws an {@link Exception} */ public <T> T time(Callable<T> event) throws Exception { final long startTime = clock.getTick(); try { return event.call(); } finally { update(clock.getTick() - startTime); } }
/** * Updates the timer with the difference between current and start time. Call to this method will * not reset the start time. Multiple calls result in multiple updates. * * @return the elapsed time in nanoseconds */ public long stop() { final long elapsed = clock.getTick() - startTime; timer.update(elapsed, TimeUnit.NANOSECONDS); return elapsed; }
private void rescaleIfNeeded() { final long now = clock.getTick(); final long next = nextScaleTime.get(); if (now >= next) { rescale(now, next); } }
/** * Creates a new {@link ExponentiallyDecayingReservoir}. * * @param size the number of samples to keep in the sampling reservoir * @param alpha the exponential decay factor; the higher this is, the more biased the reservoir * will be towards newer values * @param clock the clock used to timestamp samples and track rescaling */ public ExponentiallyDecayingReservoir(int size, double alpha, Clock clock) { this.values = new ConcurrentSkipListMap<>(); this.lock = new ReentrantReadWriteLock(); this.alpha = alpha; this.size = size; this.clock = clock; this.count = new AtomicLong(0); this.startTime = currentTimeInSeconds(); this.nextScaleTime = new AtomicLong(clock.getTick() + RESCALE_THRESHOLD); }
public <T> T time(final String tag, final String name, ZooKeeperCallable<T> callable) throws KeeperException { final long startTime = clock.getTick(); try { return callable.call(); } catch (KeeperException e) { checkException(e, tag, name); throw e; } catch (Exception e) { Throwables.throwIfUnchecked(e); throw new RuntimeException(e); } finally { metrics.updateTimer(name, clock.getTick() - startTime, TimeUnit.NANOSECONDS); } }
@Override public double getMeanRate() { if (getCount() == 0) { return 0.0; } else { final double elapsed = clock.getTick() - startTime; return getCount() / elapsed * TimeUnit.SECONDS.toNanos(1); } }
private void tickIfNecessary() { final long oldTick = lastTick.get(); final long newTick = clock.getTick(); final long age = newTick - oldTick; if (age > TICK_INTERVAL) { final long newIntervalStartTick = newTick - age % TICK_INTERVAL; if (lastTick.compareAndSet(oldTick, newIntervalStartTick)) { final long requiredTicks = age / TICK_INTERVAL; for (long i = 0; i < requiredTicks; i++) { m1Rate.tick(); m5Rate.tick(); m15Rate.tick(); } } } }
@Test public void cachingExceptionHandlingGaugeChangesToNewValues() { when(testSupplier.get()).thenReturn(8L).thenReturn(11L); when(clock.getTick()).thenReturn(0L).thenReturn(TrackerUtils.DEFAULT_CACHE_INTERVAL.toNanos() + 1); assertThat(cachingExceptionHandlingGauge.getValue()).isEqualTo(8L); assertThat(cachingExceptionHandlingGauge.getValue()).isEqualTo(11L); verify(testSupplier, times(2)).get(); }
@Test public void doesNotCallSupplierOnRequestsWithinRetriggerInterval() { when(mockClock.getTick()).thenReturn(0L, 1L, 2L); AtomicLong timestampValue = new AtomicLong(0L); TimestampTracker.registerTimestampForTracking( mockClock, metricsManager, FAKE_METRIC, timestampValue::incrementAndGet); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(1L); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(1L); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(1L); }
@Test public void timestampTrackersDoNotThrowEvenIfUnderlyingSupplierThrows() { when(mockClock.getTick()).thenReturn(0L, CACHE_INTERVAL_NANOS); TimestampTracker.registerTimestampForTracking(mockClock, metricsManager, FAKE_METRIC, () -> { throw new IllegalArgumentException("illegal argument"); }); getGauge(FAKE_METRIC).getValue(); }