Created
February 5, 2018 18:47
-
-
Save kakai248/a931e76d594699bfb3d85c55faecd7a6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private TimedCacheSource<Discover> discoverObservable = TimedCacheSource.createWithTimeout(30, TimeUnit.SECONDS); | |
public Single<Discover> getProviders() { | |
return discoverObservable.switchIfEmpty(fetchProviders().doOnSuccess(discoverObservable)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Maybe that caches a value for an amount of time. Every time it is subscribed it either | |
* emits the cached value if it isn't expired or just completes. | |
* <p/> | |
* Default timeout is 5 minutes. | |
* | |
* @param <T> the value type received and emitted by this Maybe subclass | |
*/ | |
public final class TimedCacheSource<T> extends Maybe<T> implements Consumer<T> { | |
private static final int DEFAULT_TIMEOUT_MS = 300000; // 5 minutes | |
private final int timeout; | |
private final TimeUnit unit; | |
private final AtomicReference<TimedValue<T>> valueRef = new AtomicReference<>(); | |
public static <T> TimedCacheSource<T> create() { | |
return new TimedCacheSource<>(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS); | |
} | |
public static <T> TimedCacheSource<T> createWithTimeout(int timeout, TimeUnit unit) { | |
return new TimedCacheSource<>(timeout, unit); | |
} | |
private TimedCacheSource(int timeout, TimeUnit unit) { | |
this.timeout = timeout; | |
this.unit = ObjectHelper.requireNonNull(unit, "unit is null"); | |
} | |
public void clear() { | |
valueRef.set(null); | |
} | |
@Override | |
public void accept(T value) { | |
valueRef.set(new TimedValue<>(value, System.currentTimeMillis())); | |
} | |
@Override | |
protected void subscribeActual(MaybeObserver<? super T> observer) { | |
TimedValue<T> value = valueRef.get(); | |
if (value != null && insideTimeWindow(value.time)) { | |
observer.onSuccess(value.value); | |
} else { | |
observer.onComplete(); | |
} | |
} | |
private boolean insideTimeWindow(long time) { | |
long now = System.currentTimeMillis(); | |
return now - time < unit.toMillis(timeout); | |
} | |
private static class TimedValue<T> { | |
private final T value; | |
private final long time; | |
TimedValue(T value, long time) { | |
this.value = value; | |
this.time = time; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment