All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.team33.patterns.expiry.tethys.Mutual Maven / Gradle / Ivy

Go to download

Provides a simple renewal mechanism for instances that are essentially reusable but expire after a certain amount of time.

The newest version!
package de.team33.patterns.expiry.tethys;

import de.team33.patterns.exceptional.dione.XSupplier;

import java.time.Instant;

class Mutual {

    private final Rule rule;
    private volatile Actual actual = now -> true;

    private Mutual(final Rule rule) {
        this.rule = rule;
    }

    /**
     * Initializes a new instance of this container type given a {@link XSupplier} for the type to be handled and
     * an intended lifetime of such instances.
     * 

* CAUTION: The given lifetime should be significantly smaller than the actually expected * life span of an instance to be handled, otherwise there may not be enough time to use a * {@linkplain #get() provided} instance successfully! * * @param newSubject the {@link XSupplier} for the instances to handle * @param maxIdle the maximum idle time in milliseconds * @param maxLiving the maximum lifetime in milliseconds */ Mutual(final XSupplier newSubject, final long maxIdle, final long maxLiving) { this(new Rule<>(newSubject, maxIdle, maxLiving)); } T get() throws X { return approved(actual); } private T approved(final Actual candidate) throws X { return candidate.isTimeout(Instant.now()) ? updated(candidate) : candidate.get(); } @SuppressWarnings("ObjectEquality") private T updated(final Actual outdated) throws X { final T result; synchronized (rule) { if (actual == outdated) { actual = new Substantial(); } result = actual.get(); } return result; } @FunctionalInterface private interface Actual { boolean isTimeout(final Instant now); default T get() throws X { throw new UnsupportedOperationException("method not supported"); } } private class Substantial implements Actual { private final T subject; private final Instant lifeTimeout; private volatile Instant idleTimeout; Substantial() throws X { final Instant now = Instant.now(); this.lifeTimeout = now.plusMillis(rule.maxLife); this.idleTimeout = now.plusMillis(rule.maxIdle); this.subject = rule.newSubject.get(); } @Override public final boolean isTimeout(final Instant now) { return (now.compareTo(lifeTimeout) > 0) || (now.compareTo(idleTimeout) > 0); } @Override public final T get() { idleTimeout = Instant.now().plusMillis(rule.maxIdle); return subject; } } private static final class Rule { private final XSupplier newSubject; private final long maxLife; private final long maxIdle; Rule(final XSupplier newSubject, final long maxIdle, final long maxLife) { this.newSubject = newSubject; this.maxIdle = maxIdle; this.maxLife = maxLife; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy