question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

3.x: recursive concat causes StackOverflowError

See original GitHub issue

Originally posted on StackOverflow.

The following code crashes with StackOverflowError and the stacktrace shows a long chain of request calls.

import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import java.util.concurrent.TimeUnit.SECONDS

fun main() {
    fun incr(n: Int): Single<Int> = Single.just(n + 1)

    fun numbers(n: Int, max: Int): Flowable<Int> = Flowable.just(n).concatWith(
        if (n < max)
            incr(n)
            .observeOn(Schedulers.single())
            .toFlowable()
            .concatMap { next -> numbers(next, max) }
        else
            Flowable.empty()
    )

    numbers(1, 10_000)
    .blockingForEach(::println)
}
Exception in thread "main" java.lang.StackOverflowError
	at io.reactivex.rxjava3.internal.subscriptions.SubscriptionArbiter.request(SubscriptionArbiter.java:135)
	at io.reactivex.rxjava3.internal.subscriptions.SubscriptionArbiter.request(SubscriptionArbiter.java:135)
	at io.reactivex.rxjava3.internal.operators.flowable.FlowableConcatMap$ConcatMapImmediate.request(FlowableConcatMap.java:215)
	at io.reactivex.rxjava3.internal.subscriptions.SubscriptionArbiter.request(SubscriptionArbiter.java:135)
	at io.reactivex.rxjava3.internal.subscriptions.SubscriptionArbiter.request(SubscriptionArbiter.java:135)
	at io.reactivex.rxjava3.internal.operators.flowable.FlowableConcatMap$ConcatMapImmediate.request(FlowableConcatMap.java:215)
	at io.reactivex.rxjava3.internal.subscriptions.SubscriptionArbiter.request(SubscriptionArbiter.java:135)
	at io.reactivex.rxjava3.internal.subscriptions.SubscriptionArbiter.request(SubscriptionArbiter.java:135)
	at io.reactivex.rxjava3.internal.operators.flowable.FlowableConcatMap$ConcatMapImmediate.request(FlowableConcatMap.java:215)

I’m not sure why there is such a chain created and if this is a result of an RxJava bug or not.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
tmankitacommented, Jul 8, 2020

Hi, I would like to pick up this issue if no one is working on it yet.

0reactions
anastrcommented, Aug 12, 2020

it looks like each time you add new couple of concatWith-concatMap operators, so while the sequence grow up it must pass the emit to the whole concatWith-concatMap couples then to the Consumer. My only proof for that is that the last ‘1000’ emits will take longer time than first one.

I’m sorry to bother, but i have a question: in this case, why the error didn’t deliver to the consumer (onError has been implemented for sure)! if the max number was 1000, error will be thrown after complete!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Clojure: Why does this give a StackOverflowError?
It's because concat produces a lazy sequence. So, when you're calling (concat a b). no actual concatenation is done unless you're trying to ......
Read more >
Why do I get stackoverflow error? - Google Groups
It looks like the error is not from the explicit recursion, but is due to concat. Someone who knows more than I do...
Read more >
Efficient multiple-stream concatenation in Java - TechEmpower
flatMap avoids the StackOverflowError issue but it comes with its own set of quirks. For example, it interacts poorly with infinite streams.
Read more >
[JDK-8025523] StackOverflowError at java.util.stream.Streams ...
Consecutive concatenation of streams may leads to stack overflow due to recursive invocation of estimateSize(): int count = 20000;
Read more >
Clojure Don'ts: Concat - Digital Digressions by Stuart Sierra
In the stack trace, we see concat and seq repeated over and over: (.printStackTrace *e *out*) ;; java.lang.StackOverflowError ;; ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found