I'm using RxJava and the concat() and first() operators:
public Observable<List<Entity>> getEntities() {
invalidateCacheIfNeeded();
return Observable
.concat(cachedEntities(), networkEntities())
.first();
}
The cachedEntities returns an Observable built from a cached list while the networkEntities method fetches the entities with Retrofit.
This works great unless two user subscribes quickly to the observables returned by getEntities(). I guess the network request of the first subscribe is not finished when the second subscribe is made. In this case, two network requests are performed. Which I want to avoid.
I tried to create a single thread Scheduler so the the execution of the second call is only carried out when the first call is over but with no luck:
mSingleThreadScheduler = Schedulers.from(Executors.newSingleThreadExecutor());
and:
public Observable<List<Entity>> getEntities() {
invalidateCacheIfNeeded();
return Observable
.concat(cachedEntities(), networkEntities())
.subscribeOn(mSingleThreadScheduler)
.first();
}
I've tried to sprinkle the subscribeOn call lower in the Observable chain but I get the same result.
Any hint?
synchronizedkeyword on yourgetEntities()declaration for your method and it should wait for a previous call to complete before allowing for another with a thread lock. - Jay Snayderconcat()call is not blocking sogetEntitiesreturns almost immediatly.synchronizedon the method won't work in this case. - fstephanyconcat()is not blocking, whatever is callinggetEntities()would be blocking while waiting for a return from the call wouldn't it? So you would thinksynchronizedwould be ok for this call if you were trying to keep it from being called multiple times. Unless I am missing something. How can it return immediately if it isn't finished its task? Maybe I can pick up a tidbit here. - Jay SnaydergetEntities()only build the Observabl (which is super fast). The real work is done when someone subscribes to this observable. But you're right my wording is probably misleading. I'll update the question to reflect the subscribing phase. - fstephany