Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

SoE on pure stream with recursion #1035

Closed
pchlupacek opened this issue Dec 27, 2017 · 6 comments
Closed

SoE on pure stream with recursion #1035

pchlupacek opened this issue Dec 27, 2017 · 6 comments
Milestone

Comments

@pchlupacek
Copy link
Contributor

pchlupacek commented Dec 27, 2017

This produces SoE:

def p : Stream[IO, Int] = 
(1 until 10000).map(Stream.emit)
.foldLeft(Stream.emit(0).covary[IO])((acc,a) => 
  acc flatMap { _ => Stream.eval(IO{()}).flatMap { _ =>  a } 
})

p.runLog.unsafeRunSync
java.lang.StackOverflowError
  at fs2.internal.Algebra$$$Lambda$3171/1646380420.apply(Unknown Source)
  at fs2.internal.FreeC$.$anonfun$mkViewL$1(FreeC.scala:90)
  at fs2.internal.FreeC$$$Lambda$3172/1984616342.apply(Unknown Source)
  at fs2.internal.Algebra$.$anonfun$uncons$7(Algebra.scala:91)
  at fs2.internal.Algebra$$$Lambda$3171/1646380420.apply(Unknown Source)
  at fs2.internal.FreeC$.$anonfun$mkViewL$1(FreeC.scala:90)
  at fs2.internal.FreeC$$$Lambda$3172/1984616342.apply(Unknown Source)
  at fs2.internal.Algebra$.$anonfun$uncons$7(Algebra.scala:91)
  at fs2.internal.Algebra$$$Lambda$3171/1646380420.apply(Unknown Source)
  at fs2.internal.FreeC$.$anonfun$mkViewL$1(FreeC.scala:90)
  at fs2.internal.FreeC$$$Lambda$3172/1984616342.apply(Unknown Source)
  at fs2.internal.Algebra$.$anonfun$uncons$7(Algebra.scala:91)
  at fs2.internal.Algebra$$$Lambda$3171/1646380420.apply(Unknown Source)
  at fs2.internal.FreeC$.$anonfun$mkViewL$1(FreeC.scala:90)
  at fs2.internal.FreeC$$$Lambda$3172/1984616342.apply(Unknown Source)
  at fs2.internal.Algebra$.$anonfun$uncons$7(Algebra.scala:91)
  at fs2.internal.Algebra$$$Lambda$3171/1646380420.apply(Unknown Source)
  at fs2.internal.FreeC$.$anonfun$mkViewL$1(FreeC.scala:90)
 ....

My gut it is related to special case of implementation in flatMap + this counters stack safety of FreeC through two consecutive viewL's in runFoldScope and uncons.

@mpilquist, @SystemFw this was discovered when implementing interruption, and I was not able to fix it in terms of current algebra and runFoldScope//uncons implementation.

@mpilquist
Copy link
Member

Can you try commenting out the special case in flatMap for emitting a singleton stream? Removing the special case will reintroduce a memory leak but it will at least confirm your hunch.

@pchlupacek
Copy link
Contributor Author

@mpilquist I have tried that just now, and as I have suspected this is unrelated. That means we do have SoE whether the special case for single element streams is there or not.

@pchlupacek
Copy link
Contributor Author

As I was tracing this down I thin the problem is definition of ViewL, which in fact escapes the tail position in streams that jump between uncons and runFoldScope.

@mpilquist
Copy link
Member

@pchlupacek Yeah I agree the issue is the non-tail position recursive call in Algebra.uncons. I'm not sure how to fix though. Maybe @pchiusano has some ideas.

@pchlupacek
Copy link
Contributor Author

@mpilquist I may be on the track to resolve this. I have introduced Algebra.Uncons, and modified runXXX that seems to work nicely and no more SoE. The approach is in interrupt branch, and changes to Algebra are here. https://github.com/functional-streams-for-scala/fs2/pull/1019/files#diff-91195044dae5827508d46a79e123c46aR19

The tests are not yet all passing, but I think the issues there are fixable.

I would appreciate your feedback. Thanks

@mpilquist
Copy link
Member

mpilquist commented Dec 30, 2017 via email

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants