Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upAsynchronous loops created with Tasks and Signal.mailbox trigger crash in stepTask #240
Comments
referenced
this issue
in srid/chronicle
May 19, 2015
referenced
this issue
in srid/chronicle
May 19, 2015
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
srid
May 19, 2015
FWIW, I hit this bug in my app and had to workaround it (see the two commits linked above).
srid
commented
May 19, 2015
|
FWIW, I hit this bug in my app and had to workaround it (see the two commits linked above). |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Dobiasd
May 20, 2015
fyi, I also bumped into this problem in one of my apps. Luckily it happens with a task, that does not harm if it fails now and then. :) So I guess I will just leave it and wait for this issue to be fixed.
Dobiasd
commented
May 20, 2015
|
fyi, I also bumped into this problem in one of my apps. Luckily it happens with a task, that does not harm if it fails now and then. :) So I guess I will just leave it and wait for this issue to be fixed. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
If you can take a swing at the fix, it would be very appreciated! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Dobiasd
May 20, 2015
@evancz I'm note sure if this was for me or not. In case it was: I would love to, but I do not even know where to start. Despite using Elm a lot, I have no clue about how it works internally. And I don't even know how I could start learning about it. :D
Dobiasd
commented
May 20, 2015
|
@evancz I'm note sure if this was for me or not. In case it was: I would love to, but I do not even know where to start. Despite using Elm a lot, I have no clue about how it works internally. And I don't even know how I could start learning about it. :D |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
evancz
May 20, 2015
Member
For anyone who can help really! You can mess with it locally by manually modifying elm-stuff/packages/elm-lang/core/Native/Task.js in your project. You can add console.log or whatever else into the JS and that'll get packaged up when you run elm-make. If you can find the error in your version of Native/Task.js that'll be the bug.
|
For anyone who can help really! You can mess with it locally by manually modifying |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
colinmccabe
Jul 15, 2015
Contributor
I'm seeing these exceptions with a Time.every that gets mapped to an Http request whose result is mailed to a view. There is no loop. The exceptions are sporadic and random and happen even when the request succeeds. Oddly, the pace of the exceptions quickens dramatically when I'm in a different browser tab.
I'm rather obsessed with this and want to fix it. Unfortunately I'm clueless about how Elm actually works. I'll do what I can.
|
I'm seeing these exceptions with a Time.every that gets mapped to an Http request whose result is mailed to a view. There is no loop. The exceptions are sporadic and random and happen even when the request succeeds. Oddly, the pace of the exceptions quickens dramatically when I'm in a different browser tab. I'm rather obsessed with this and want to fix it. Unfortunately I'm clueless about how Elm actually works. I'll do what I can. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
colinmccabe
Jul 19, 2015
Contributor
This is what is causing the error in my case:
- A task chain (not sure what to call this) containing an
Asynctask somewhere within it gets passed to theregister()function and is placed on theworkQueue(Task.js#L83) register()callsrunTask()which then callsstepTask(), where theAsynctask gets replaced by an empty placeholder object (Task.js#L140).- At some point,
onComplete()runs (Task.js#L71) and passes the chain torunTask()which in turn callsstepTask(). Most of the time, the empty placeholder object has been replaced by a Success object by theasyncFunction(Task.js#L144) and all is well. Occasionally, an empty placeholder object is there, andstepTask()chokes on it.
One theory is that workQueue[0] gets overwritten by the value of the next Async task before runTask() runs for the preceding Async. This would explain the presence of the placeholder object.
One bit of evidence in favor of this theory is that removing the setTimeout() wrapper around runTask() makes the exception go away, possibly because this gives no time for workQueue[0] to be overwritten.
function onComplete()
{
workQueue.shift();
if (workQueue.length > 0)
{
runTask(workQueue[0], onComplete);
}
}
Of course this change probably causes bad effects elsewhere.
|
This is what is causing the error in my case:
One theory is that One bit of evidence in favor of this theory is that removing the
Of course this change probably causes bad effects elsewhere. |
added a commit
to colinmccabe/core
that referenced
this issue
Jul 21, 2015
pushed a commit
that referenced
this issue
Jul 21, 2015
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jvoigtlaender
Jan 19, 2016
Contributor
Has #304 completely fixed this? If so, the issue should be closed. Otherwise, what is still problematic?
|
Has #304 completely fixed this? If so, the issue should be closed. Otherwise, what is still problematic? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jvoigtlaender
Jan 19, 2016
Contributor
The previous comment is really a question for @colinmccabe just as for anybody else. If you don't have the repository rights to close issues here, I have, but I need confirmation that the issue is really resolved.
|
The previous comment is really a question for @colinmccabe just as for anybody else. If you don't have the repository rights to close issues here, I have, but I need confirmation that the issue is really resolved. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
colinmccabe
Jan 20, 2016
Contributor
I used "mitigate" because I wasn't sure that the commit would fix it, but I think it does. I haven't seen another runtime exception in my project.
Here is the problematic series of events in the old code:
onComplete()is called after a task completes. It shifts the task off theworkQueue, which becomes empty.onComplete()callssetTimeout()and returns. Control could shift to anywhere!- Control moves to
register()because a new task happens to be coming in. The new task is pushed intoworkQueue[0]. TheworkQueueis now 1 item long, soregister()callsrunTask(workQueue[0], ...).runTask()callsstepTask()which replaces async tasks by empty placeHolder objects. - Control moves to the code inside the
setTimeout()inonComplete(). Since theworkQueueis not empty, it callsrunTask(workQueue[0], ...)a second time, before the async tasks have a chance complete! The empty placeholder objects cause the runtime exception.
Moving the if check outside of the setTimeout removes the possibility of preemption, ensuring that step 3) can never happen between steps 2) and 4).
If this makes sense, feel free to close.
|
I used "mitigate" because I wasn't sure that the commit would fix it, but I think it does. I haven't seen another runtime exception in my project. Here is the problematic series of events in the old code:
Moving the if check outside of the setTimeout removes the possibility of preemption, ensuring that step 3) can never happen between steps 2) and 4). If this makes sense, feel free to close. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Dobiasd
Jan 20, 2016
I also do not observe these errors any more in my project that previously had them in abundance.
Dobiasd
commented
Jan 20, 2016
|
I also do not observe these errors any more in my project that previously had them in abundance. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Sounds all good, so I'm closing this issue. Thanks! |
pchiusano commentedMay 6, 2015
Here is a minimal gist demonstrating the problem and showing a workaround. Clicking rapidly generates:
pointing to this line in
Task.jsstepTask.The problematic pattern seems to be signals with 'asynchronous loops', whose output generates asynchronous tasks that affect the future value of that signal. I worked around it with an intermediate 'relay' mailbox, but that seems pretty kludgy.
Background discussion on the mailing list