private CheckResult<S> checkUpdateRequired() {
        final long nowMs = System.currentTimeMillis();
        if (nowMs == UNINITIALISED) {
            LOGGER.debug("Uninitialised");
            return CheckResult.updateRequired(NullSafe.get(stateSupplier, Supplier::get));
        } else {
            final long oldNextCheck = nextCheckEpochMs.get();
            LOGGER.debug("oldNextCheck: {}, nowMs: {}", oldNextCheck, nowMs);
            if (nowMs > oldNextCheck) {
                if (stateSupplier == null) {
                    // No state to check
                    LOGGER.debug("Stateless update required");
                    return CheckResult.updateRequired(null);
                } else {
                    final S newState = stateSupplier.get();
                    if (Objects.equals(state, newState)) {
                        // No state change
                        LOGGER.debug("State un-changed");
                        return CheckResult.noUpdateRequired();
                    } else {
                        LOGGER.debug("Stateful update required");
                        return CheckResult.updateRequired(newState);
                    }
                }
            } else {
                return CheckResult.noUpdateRequired();
            }
        }
    }
State dependant version where we only want to update the value if the state has changed.

@param maxCheckInterval The max interval to call stateSupplier to determine if the valueSupplier needs
                        to be called to update the value.
@param valueSupplier    Will be called on first call of {@link CachedValue#getValue()}
                        then any time the value supplied by stateSupplier changes. If multiple
                        threads call {@link CachedValue#getValue()} at once valueSupplier
                        may be called by each thread. Should be side effect free.
@param stateSupplier    Will generally be called once per checkInterval unless multiple threads
                        call {@link CachedValue#getValue()} at once, in which case
                        it may be called by multiple threads at once. Should be side effect free.
                        Value returned must implement equals method to determine if it has changed.
stroom-util/src/main/java/stroom/util/concurrent/CachedValue.java