liblucy
liblucy copied to clipboard
Allow for stopping spawned actors
There appears not to be a lucy-native way for stopping spawned actors. Pointed out by @VanTanev on a recent stream of mine.
Normally you would call context.actorRef.stop() in an action, right? You an currently do that, I think. But it might be nice to have a lucy native way. Maybe:
machine todoItem {
state idle {}
}
machine app {
state idle {
new => assign(todo, spawn(todoItem))
delete => stop(todo)
}
}
This looks cool. One thing which might affect spawn in general is how we represent arrays of spawned actors? Though perhaps this should be the topic for another issue.
Yeah lists are going to be needed eventually, I intentionally avoided that so far.
Normally you would call
context.actorRef.stop()in an action, right?
Unfortunately, no. The proper way to stop a spawned child is this:
{
on: {
STOP: actions.pure((ctx) => {
const assignAction = assign({ actorRef: null })
const stopAction = actions.stop(ctx.actorRef)
return [assignAction, stopAction]
})
}
}
XState v5 should improve this, but for now, the above code is the only way to stop a child actor without leaking memory. Simply calling ctx.actorRef.stop() still leaves a dangling reference in machine.children, while actions.stop() will properly clean up all references.
Because assign() executes before all other actions, you can't simply have:
actions: [
// doesn't work, assign() will execute before stop(), and `ctx.actorRef` will be null, so nothing will be stopped.
actions.stop(ctx => ctx.actorRef),
assign({ actorRef: null })
]
It must be wrapped in actions.pure().
@VanTanev Thank you! Seems like something Lucy can do the gross part for you.