-
-
Notifications
You must be signed in to change notification settings - Fork 504
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
Task.delay test fails #1626
Comments
I can confirm the same problem on The problem is not systematic, I mean:
|
Tested fails under v2.11.5 and v2.11.4, but was OK in v2.11.3, seems broken by #1591. /cc @mikearnaldi |
Using parallel combinators while relying on ordering is a funny combo. Apparently microtasks execution order isn't guaranteed. |
@mikearnaldi Do you mean it's uncommonly used code example from docs? I think these two should exchangeable behavior-wise here: import { sequenceT } from '../../src/Apply'
import * as T from '../../src/Task'
- await sequenceT(T.ApplyPar)(fa, fb, fc, fd)()
+ await T.sequenceArray([ fa, fb, fc, fd])() |
@mikearnaldi @imcotton The weird thing is that output is in reverse order. I'm asking myself whether there is a way to fix it. Changing the Lines 131 to 132 in ee7c1da
with: export const ap: <A>(fa: Task<A>) => <B>(fab: Task<(a: A) => B>) => Task<B> = (fa) => (fab) => () =>
Promise.all([fab(), Promise.resolve().then(fa)]).then(([f, a]) => f(a)) removing the deferred promise for |
No, one is doing things in sequence and the other one in parallel which has completely different guarantees, the output should be the same (and it is) ofc but not the behaviour.
Calling We may get away with a different approach that centralize suspension in a suspended loop that will respect the order in starting the operations but generally speaking you should never rely on order of execution of parallel things, in fact the sole reason we can even talk about that is because JS is single threaded. |
Just make sure we were on the same page,
But it rather not in v2.11.5 and v2.11.4 which lead OP to this issue. |
So Line 484 in ee7c1da
Promise.all so it is true that it is parallel but it is not an alias, in fact I believe it was implemented that way to get a degree of safety in a previous PR.
The output of the program is the same, the execution order is not guaranteed to be the same. The OP issue comes from observing the execution order via: T.fromIO(() => {
log.push(message)
}) This isn't the same as collecting the output, in fact the result of |
Ok, I agree with @mikearnaldi, the behavior is different but the output is the same, it's not a bug. I think we should just change the test in the example. |
I opened a PR #1639 if you want to review it. It just checks delayed task. |
Seems like the only real needed suspension point is Not too sure why that would be the case though. |
I come to agree to fix the example code as in #1639 since micro tasks are not in guaranteed ordering, as long as |
I agree that the tests and demos should show code that only rely on guaranteed behaviour but also it's very strange that suspending map changes the behaviour, microtasks don't have a strong guarantee but de-facto the order of execution is preserved... Promise.resolve().then(() => {
log("a")
})
Promise.resolve().then(() => {
log("b")
}) logs |
🐛 Bug report
I was working to a new feature and before to open a PR I run
npm test
. It fails creating docs becauseTask/delay
tests failed.Current Behavior
Test file:
Expected behavior
Same order on my system (?)
Reproducible example
Command:
Suggested solution(s)
I don't know if it's a bug or a different behaviour on my system (MacOS), but I tested it even with docker.
Additional context
I know it's different, but the following snippet using
Promise.all()
works as expected.Your environment
Same as master@13e94a4183c7f7878fc7a4c99c9b3c170672916d branch.
OS:
MacOS Monterey 12.0.1
Node:
v17.0.1
Tested even with docker-for-mac with
node:12
:v12.22.7
The text was updated successfully, but these errors were encountered: