#OTP Task: not killing task after timeout, bug or feature?

1 messages · Page 1 of 1 (latest)

jovial spruce
#
  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)
old knot
#

The idea is that you'd call it again, but perhaps killing is a better API

jovial spruce
#

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)
    }
old knot
#

We'd need to have a discussion around API design

#

Doing that means we can't wait multiple times

still hound
#

task.await_or_kill?

jovial spruce
#

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.