Closed fougere-mike closed 8 years ago
Hi.
Whenever I see the use of Observable.create
or Observable.lift
, that is a sign for trouble. Why did you implement all those operators instead of using standard RxJava methods?
Regardless, one possible source for the problems is just
because it doesn't support backpressure and thus it can overflow the request tracking inside concat
which throws an IllegalStateException
from produced
. It is possible this exception gets swallowed somewhere and thus the stream ends up hanging. Try and using just(m).onBackpressureBuffer()
everywhere and see if it still hangs.
Thanks for the reply. I've tried adding onBackpressureBuffer()
to all the .just
calls, but it has no effect.
To answer your question: I'm using custom operators to achieve behaviour that I don't believe is available as a single operator. For example: then
is equivalent to ignoreElementsThen()
which is not yet available (currently awaiting merge #3443). onNextDo
is for async side-effects. It's doOnNext
's async cousin. I realise I can achieve the same effect by chaining several existing rx operators, but that leads to a lot of code clutter where I have to use the same 3 or 4 operators over and over again. It's much cleaner imo to use a custom operator.
With that said, I'm clearly an rx newb so if there are better solutions I'm all ears!
I don't see anything outstanding in your custom implementations so my guess is that the problem may be in the unshown code.
To rule out concat
, use merge
with maxConcurrency = 1
which subscribes to a single source at a time.
You are correct. The issue was in the unshown code (of course, haha). I had been using a combination of operators to concatIfEmpty
-- I just removed those lines and it stopped hanging.
A quick google search revealed the switchIfEmpty
operator -- which solves the problem and doesn't hang.
All appears well. I just need to spend a bit more time learning all the built-ins. Thanks for the help!
Hi all,
For the last couple of days I've been struggling with what appears to be a concurrency issue. I've got two streams concat'd together with Observable.concat(). The first stream completes successfully, but the second stream is never subscribed; effectively stopping execution. Every once in a while (maybe 1/100 executions) I get a "good" execution which actually does complete and everything looks dandy.
I've tried making a test case which illustrates the issue, but I can't seem to reproduce it in stand-alone code. At this point I'm fairly stumped, and I'm hoping someone on here can point me in the right direction.
The test case I've been using to try and reproduce is included below. It illustrates what I'm trying to accomplish. There are two operations concatenated together: cache, publish. The cache operation is a concatenation of the update and delete operations. All cache operations should occur on the cache scheduler, while the publish operation should occur on the publish scheduler. This is to prevent concurrent access to the cache's underlying data store.
In my actual code the 'cache' operation is subscribed to, and it executes the first of its two inner operations (update, but not delete). The publish operation is obviously also never executed since it depends on the cache operation completing.
Using the debugger I've determined that when the cache update operation calls
onCompleted()
, it ends up in theOperatorConcat
at this method with an emptyqueue
:I believe this is what causes the cache delete operation to not be subscribed (the empty
queue
). It appears that the same thread which executes the cache update operation is also used to callsubscribeNext
, so it doesn't have a chance to actually complete and update thequeue
with the next operation. I could be totally off base here, and as I mentioned before I can't seem to reproduce this with tests.Does anyone have an idea what could be going wrong? It seems like it's probably my fault, but I can't figure out what I've done wrong.
Note: I've tried removing everything from the bodies of cache update and cache delete to no avail. It appears that even when all the operations do is call
subscriber.onCompleted()
the concat operator still gets stuck. But not in tests...Here's the test case: