-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
support cancelling child subroutines when parent routine is cancelled #17
Conversation
thanks @aikoven for your contribution. For subroutine cancellation I think auto cancellation of child subroutines isn't a good idea. IMO it'd be better to let the developer explicitly have control of when to trigger the cancellation. function* subtask2() {
try { ... }
catch(err) {
doCleanup
}
}
function* subtask() {
const subtask = yield fork(subtask2)
...
try {
...
} catch(err) {
needToDoBeforeChildcancellation()
subtask.cancel() // explicit cancellation of subtasks
}
}
function mainTask() {
const task = yield fork(subtask)
...
task.cancel()
} (As a side note I think your code doesnt handle the case if a Saga forked more than one subroutine) I think also we should also throw a more specific error, something like |
That's a different case: I covered subroutines that were invoked using |
Also it seems to be nontrivial to make a custom |
Just noticed that my code actually cancels |
Thanks for drawing my attention on this. I was too focused on forked tasks. There are some more issues i'd like to discuss 1- taking into account that a task can be blocked on multiple function* task() {
const [r1, r2] = yield [call(subtask1), call(subtask2)]
} we need to cancel both subtasks if 2- making task cancellation declarative. so instead of 3- Do you think we should automatically cancel function* task() {
...
const {timeout} = yield race({
timeout: call(delay, 1000),
subtask: call(subtask)
});
} if |
const authLoopTask = yield fork(authorizeLoop, storedToken);
const {signOutAction} = yield race({
signOutAction: take(SIGN_OUT),
authLoop: join(authLoopTask)
});
if (signOutAction) {
authLoopTask.cancel();
// ...
}
const {signOutAction} = yield race({
signOutAction: take(SIGN_OUT),
authLoop: call(authorizeLoop, storedToken)
});
if (signOutAction) {
// ...
} So probably it's a good idea, but I need to think a bit more about this. |
@yelouafi Done. I decided not to go with cancellable promises because there is no convention and it would result in additional complications with making chained promises cancellable as well. |
@aikoven great work! thanks 👍 . My only doubt is on the automatic race cancellation. we should cancel the cancellable/competing effects. I looked quickly, but it seems like you're cancelling subroutines of the Saga that is running the actual effects. |
@aikoven |
support cancelling child subroutines when parent routine is cancelled
You are right, my code will go wrong if there was another yield [
call(subroutine1),
race({
subroutine2: call(subroutine2),
subroutine3: call(subroutine3),
})
] If race finishes before |
Oops! merged too soon! |
I made a fix. I can make another PR, or you can revert the merge 😀 |
I reverted the merge. Not sure however if this will reactivate the PR |
No description provided.