assert_owner(task)
case process.select(task.selector, timeout) {
// The task process has sent back a value
Ok(FromSubject(x)) -> {
process.demonitor_process(task.monitor)
Ok(x)
}
// The task process crashed without sending a value
Ok(FromMonitor(process.ProcessDown(reason: reason, ..))) ->
Error(Exit(reason))
// The task process is alive but has not sent a value yet
Error(Nil) -> Error(Timeout)
}
}```
If I following code correctly task process did not stoped (killed or send_abnormal_exit), we cannot get info back from task and potentially buggy implementation of task work will stack forever.
also owner process did not demonitor_process so down & success messages are sent to parent process, in my case actor. I guess
1 msg result of success finish of task:
=WARNING REPORT==== 13-Mar-2023::18:24:23.776010 ===
Actor discarding unexpected message: #(//erl(#Ref<0.3691924696.386400257.58946>), Ok([]))
and second is for task process down:
=WARNING REPORT==== 13-Mar-2023::18:24:23.776111 ===
Actor discarding unexpected message: DOWN(//erl(#Ref<0.3691924696.386400257.58947>), Process, //erl(<0.10505.0>), Normal)
#OTP Task: not killing task after timeout, bug or feature?
1 messages · Page 1 of 1 (latest)
The idea is that you'd call it again, but perhaps killing is a better API
Do you open to accept PR on this?
testing locally this LGTM:
// The task process is alive but has not sent a value yet
Error(Nil) -> {
process.demonitor_process(task.monitor)
process.unlink(task.pid)
process.send_abnormal_exit(task.pid, "Timeout")
Error(Timeout)
}
We'd need to have a discussion around API design
Doing that means we can't wait multiple times
task.await_or_kill?
my 5cents: I think task is useful as short running process and meant to be used when you need to compute smth in parallel at "hand" otherwise I think long running process (actor) may be better solution. API wise I think default version should safer version: as of now await(task.async(fn(){ ... eat all resources here forever ... }) very unintuitive. So I would prefer default api to kill and maybe adding task.await_keep_alive.