@Override
    public boolean refresh(final Consumer<Refreshable> onRefreshAction) {
        final boolean didWork;
        if (updateFunction == null) {
            didWork = false;
        } else {
            synchronized (this) {
                final FetchTokenResult fetchTokenResult = updateFunction.apply(this);
                if (fetchTokenResult != null) {
                    try {
                        this.mutableState = createMutableState(
                                Objects.requireNonNull(fetchTokenResult.tokenResponse()),
                                Objects.requireNonNull(fetchTokenResult.jwtClaims()));
                        NullSafe.consume(this, onRefreshAction);
                        didWork = true;
                    } catch (Exception e) {
                        LOGGER.error("Error updating token for userIdentity: {}",
                                LogUtil.typedValue(userIdentity), e);
                        throw e;
                    }
                } else {
                    LOGGER.trace("Function returned null, can't update state");
                    didWork = false;
                }
            }
        }
        return didWork;
    }
@return The time the token will expire (with a small buffer before the actual expiry included)
stroom-security/stroom-security-common-impl/src/main/java/stroom/security/common/impl/UpdatableToken.java