Class MonotonicClockImpl

java.lang.Object
org.apache.polaris.ids.impl.MonotonicClockImpl
All Implemented Interfaces:
AutoCloseable, org.apache.polaris.ids.api.MonotonicClock

@ApplicationScoped public class MonotonicClockImpl extends Object implements org.apache.polaris.ids.api.MonotonicClock
Monotonic clock implementation that leverages System.nanoTime() as the primary monotonically increasing time source, provided via nanoTime(). System.currentTimeMillis() is used to provide a monotonically increasing wall clock provided via currentInstant(), currentTimeMicros() and currentTimeMillis().

The implementation starts a single "tick-thread" polling the wall clock to calculate the adjustment that is necessary to provide the values for currentTime*().

Serving the current instant or "current time micros" however is a bit more complex, as the wall-clock source only has millisecond precision, but the instant has nanosecond precision. This means that the value returned for "current instant" needs to be created from the "nanosecond time" and involving an "adjustment" value. That "adjustment" is also updated by the tick-thread and represents the difference of the current nano-time and system wall clock, considering the fact that the system wall clock can go backwards or forwards or not being updated every millisecond.

This implementation expects that the wall clock in nanoseconds since epoch can be represented by the values in the range 0 .. Long.MAX_VALUE. This implementation must be adapted approaching the year 2262 (approx 292 years fit into this range).

Regarding "short-time" Thread.sleep() be aware of JDK-8306463 and JDK-8305092.

Even with very minimal sleep durations, the actual sleep time depends on the OS and in particular its scheduler. Sleep times have been measured to vary between some microseconds up to 2ms.

  • Constructor Details

    • MonotonicClockImpl

      protected MonotonicClockImpl(boolean dummy)
      Constructor for MutableMonotonicClock.
  • Method Details

    • newDefaultInstance

      public static org.apache.polaris.ids.api.MonotonicClock newDefaultInstance()
    • setup

      protected void setup()
    • tick

      protected void tick()
      Called regularly to adjust to wall-clock drift, if the wall-clock adjust into the future.
    • start

      protected MonotonicClockImpl start()
    • close

      @PreDestroy public void close()
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface org.apache.polaris.ids.api.MonotonicClock
    • currentTimeMicros

      public long currentTimeMicros()
      Specified by:
      currentTimeMicros in interface org.apache.polaris.ids.api.MonotonicClock
    • currentTimeMillis

      public long currentTimeMillis()
      Specified by:
      currentTimeMillis in interface org.apache.polaris.ids.api.MonotonicClock
    • currentInstant

      public Instant currentInstant()
      Specified by:
      currentInstant in interface org.apache.polaris.ids.api.MonotonicClock
    • nanoTime

      public long nanoTime()
      Specified by:
      nanoTime in interface org.apache.polaris.ids.api.MonotonicClock
    • sleepMillis

      public void sleepMillis(long millis)
      Specified by:
      sleepMillis in interface org.apache.polaris.ids.api.MonotonicClock
    • waitUntilTimeMillisAdvanced

      public void waitUntilTimeMillisAdvanced()
      Specified by:
      waitUntilTimeMillisAdvanced in interface org.apache.polaris.ids.api.MonotonicClock
    • afterAdjust

      protected void afterAdjust()
    • systemCurrentTimeMillis

      protected long systemCurrentTimeMillis()
    • systemNanoTime

      protected long systemNanoTime()