-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
StackOverflowError in chained Future.flatMap calls #6932
Comments
Imported From: https://issues.scala-lang.org/browse/SI-6932?orig=1 |
@retronym said (edited on Jan 7, 2013 1:48:51 PM UTC): |
@retronym said: retronym/scala@scala:2.10.x...retronym:topic/eager-load-non-fatal-2 |
@jroper said: |
@viktorklang said: |
@viktorklang said: |
@retronym said: |
@adriaanm said (edited on Jan 24, 2013 11:17:24 PM UTC): |
@pchiusano said: |
@viktorklang said: The reason we didn't go that route is that we consider that to be a disadvantage, i.e. the programmer has to make choices about execution rather than flow. |
@pchiusano said: Here's updated code, if you are interested: It is a different library than what you have in the sense that Future does not necessarily represent a running computation. Until you call start, run, or runAsync, nothing is happening. This greatly simplifies the implementation - there are no race conditions to worry about, where a listener registers itself at the same time the promise is completing on its own. I'll probably port this to scalaz pretty soon so we can see how it works out there. |
First, a simple reproduction of the bug:
This will throw a crazy exception with 1000 causes, the root being a StackOverflowError. Note if running this in the repl, or anywhere, you may instead get NoClassDefFoundErrors. This is because something is trying to handle the initial error deep in the stack (probably shouldn't be), which triggers a class to be loaded, which throws another StackOverflowError, which results in the NoClassDefFoundError.
Here's the implementation of flatMap, which clearly shows the issue:
The internalExecutor executes the onComplete callback in the same thread. So, when promises returned by flatMap are used as the promise to be returned by another flatMap callback function, and this is done enough times, you get a StackOverflowError.
This is not an uncommon situation in iteratees, which use many many futures and often chain them together in very long chains (for very long streams), and both the Play core developers and Play users have found this to be an issue all over the place. Currently we fix it with a call like this:
But I don't think this is the right solution to the problem, and it seems to come up all over the place.
Suggested solution is to use an execution context that doesn't redeem the flatMap promise is the same thread.
The text was updated successfully, but these errors were encountered: