I have the following scenario: I have an object called Foo
that my application is interested in. This Foo
object comes from a remote service, and I would like to cache this instance locally and keep using it until a certain amount of time has passed.
So far, I've tried creating a FooState
class that contains the instance of Foo
along with a timestamp indicating the time the Foo
was fetched in milliseconds:
public class FooState {
private Foo foo;
private long timestamp;
/* Constructor and getters */
}
Now, so far I've come up with this code that uses concat:
public Observable<Foo> foo() {
return Observable.concat(local(), remote())
.takeFirst(fooState -> fooState.getTimestamp() >= System.currentTimeMillis())
.map(fooState -> fooState.getFoo())
.defaultIfEmpty(new Foo());
}
private Observable<FooState> local() {
return Observable.just(cache.hasFooState() ? cache.getFooState() : new FooState(null, 0));
}
private Observable<FooState> remote() {
return api.getFoo()
.map(foo -> new FooState(foo, System.currentTimeMillis() + ONE_DAY_MILLIS)
.doOnNext(fooState -> {
cache.save(fooState);
});
}
Basically, if there's a cached value, I want to use it as long as the timestamp isn't expired. If the timestamp is expired or there is no cached value, I want to fetch from the remote service and cache the result.
Is there a cleaner way to implement this use case? I'm kind of new to RxJava and I was wondering if any Rx-gurus knew of a better way to handle this scenario.