Skip to content

Instantly share code, notes, and snippets.

@hashbrown
Last active October 18, 2015 00:26
Show Gist options
  • Save hashbrown/3510feb3591a5b807973 to your computer and use it in GitHub Desktop.
Save hashbrown/3510feb3591a5b807973 to your computer and use it in GitHub Desktop.
Caching and invalidating replayable observables
Stack<AuthenticationRequestHolder> cachedRequest = new Stack<>();
public Observable<AuthenticationResult> login(final AuthenticationRequest request) {
AuthenticationRequestHolder cached = cachedRequest.isEmpty()?null:cachedRequest.pop();
if (cached != null && cached.request.equals(request)) {
cachedRequest.push(cached);
return cached.result;
}
// make new request
Observable<AuthenticationResult> result = Observable.create(new Observable.OnSubscribe<AuthenticationResult>() {
@Override
public void call(Subscriber<? super AuthenticationResult> observer) {
try {
boolean ok = someAuthAPIRequest();
if (ok) {
observer.onNext(new AuthenticationResult(true, Collections.EMPTY_LIST));
} else {
observer.onNext(new AuthenticationResult(false, Collections.singletonList("Invalid username or password")));
}
observer.onCompleted();
} catch (Exception e) {
observer.onError(e);
}
}
}).doOnEach(new Action1<Notification<? super AuthenticationResult>>() {
@Override
public void call(Notification<? super AuthenticationService.AuthenticationResult> notification) {
// determine if the result can remain cached to serve future requests
switch (notification.getKind()) {
case OnNext:
if(!((AuthenticationResult)notification.getValue()).authenticated){
cachedRequest.pop();
}
break;
case OnError:
cachedRequest.pop();
break;
}
}
}).replay().autoConnect();
cachedRequest.push(new AuthenticationRequestHolder(request, result));
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment