1

When testing some of my code with custom expiry durations, I needed to set the clock time in an Hazelcast instance, very much like how I could set the time using a custom Ticker in Caffeine caches.

I found that this isn't documented anywhere and there isn't any questions on it.

JRG
  • 4,037
  • 3
  • 23
  • 34
Isen Ng
  • 1,307
  • 1
  • 11
  • 23

1 Answers1

0

Upon tracking the source code of HazelcastInstance, a custom clock can be implemented if you set the system property, com.hazelcast.clock.impl

This is how Hazelcast loads their clock

package com.hazelcast.util;

...

public final class Clock {

    private static final ClockImpl CLOCK;
    private Clock() {
    }

    /** Returns the current time in ms for the configured {@link ClockImpl} */
    public static long currentTimeMillis() {
        return CLOCK.currentTimeMillis();
    }

    static {
        CLOCK = createClock();
    }

    static ClockImpl createClock() {
        String clockImplClassName = System.getProperty(ClockProperties.HAZELCAST_CLOCK_IMPL);
        if (clockImplClassName != null) {
            try {
                return ClassLoaderUtil.newInstance(null, clockImplClassName);
            } catch (Exception e) {
                throw rethrow(e);
            }
        }

        String clockOffset = System.getProperty(ClockProperties.HAZELCAST_CLOCK_OFFSET);
        long offset = 0L;
        if (clockOffset != null) {
            try {
                offset = Long.parseLong(clockOffset);
            } catch (NumberFormatException e) {
                throw rethrow(e);
            }
        }
        if (offset != 0L) {
            return new SystemOffsetClock(offset);
        }

        return new SystemClock();
    }
}

So, to set this clock, we'll need to set the system property with our own clock,

public class MyHazelcastCacheTest {
    static {
        // set unit test time travelling clock
        System.setProperty(ClockProperties.HAZELCAST_CLOCK_IMPL, TimeTravellingStaticClock.class.getName());
    }

    private void timeTravel(Clock clock) {
        TimeTravellingStaticClock.timeTravel(clock);
    }

    private void undoTimeTravel() {
        TimeTravellingStaticClock.undoTimeTravel();
    }

    private static class TimeTravellingStaticClock extends com.hazelcast.util.Clock.ClockImpl {
        private static Clock sClock = Clock.systemUTC();

        public TimeTravellingStaticClock() {
            // nothing
        }

        public static void timeTravel(Clock clock) {
            sClock = clock;
        }

        public static void undoTimeTravel() {
            sClock = Clock.systemUTC();
        }

        @Override
        protected long currentTimeMillis() {
            return sClock.millis();
        }
    }
}
Isen Ng
  • 1,307
  • 1
  • 11
  • 23