mdbergmann / cl-gserver

Sento - Actor framework featuring actors and agents for easy access to state and asynchronous operations.
https://mdbergmann.github.io/cl-gserver/index.html
Apache License 2.0
196 stars 14 forks source link

Forced stop as a message #94

Closed mdbergmann closed 2 weeks ago

mdbergmann commented 1 month ago

Which acts similar to act-cell:stop method, but it more aligned with actor interface.

adlai commented 2 weeks ago

Here's how I do this in my actor.lisp, which is probably the most notable [ab]user of ChanL.

adlai commented 2 weeks ago

Also important is where the :halt command gets recv-ed.

To save you the trouble of distangling all that dense code, I'll paraphrase the highlighted code as follows: the chanl tasks that loop and perform each actor's work have a catch form as the topmost form in their body, and receiving the :halt keyword in the blessed control channel triggers the throw which immediately ends that task without queuing its successor task.

mdbergmann commented 2 weeks ago

Thanks. That looks straight forward. Indeed, :halt, or maybe I call it :terminate should immediately stop the message processing, but also discard any messages currently processing and any message still in the queue. Since the actor potentially doesn't operate its own thread but its mailbox is handled by one of the message-dispatcher threads it's not super trivial, but :terminate/:halt could just call stop function, which already implements what I want (or I think it does at least). Using :terminate should also notify watchers and distribute a terminated message.

adlai commented 2 weeks ago

its mailbox is handled by one of the message-dispatcher threads it's not super trivial

this is precisely the sort of complexity that ChanL strove to avoid; one thread per task, and in my hacky actors file, one task per actor. this invariant is not perfectly maintained in the remainder of ScalpL, although I am working towards restoring it.

mdbergmann commented 2 weeks ago

Yeah, well. Actor systems still have a bit of a different use case. Actors are supposed to maintain state in a thread-safe manner. And potentially you have very many. I.e. I use Sento for Chipi (the house automation bus project) where every light, switch, window sensor and every rule definition and persistence handler are represented by an actor that maintains their state. This all doesn't require more than just a very few threads. Also Sento implements asynchronous ask pattern by spawning an anonymous actor that waits for a reply. Other runtimes have virtual or green threads that allow this kind of things naturally, like Erlang, but in CL this sort of thing is not possible without slightly more complexity.

adlai commented 2 weeks ago

I don't think the flow I wrote works well in that case, because you couldn't predict which actors could be the ones terminating one that was given the :terminate message; similar to how you could know that if there are two light switches that toggle one bulb, then its state is effected only by one of those two switches.

edit, in case amateur grammar police read along: one bulb can be affected by multiple switches, yet have its voltage effected by touching any single switch. this is a common gimmick indispensible for corridor lighting!

mdbergmann commented 2 weeks ago

Yeah, ChanL is for running parallel tasks, not for maintaining state. But that's all fine.

adlai commented 2 weeks ago

Indeed, :halt, or maybe I call it :terminate should immediately stop the message processing, but also discard [...]

Have you considered :break? I realize the name collision against CL:BREAK, however, despite this, it benefits from the intuition of tripping a circuit braker to turn off all lights in some section of a building.

mdbergmann commented 2 weeks ago

I don't think the flow I wrote works well in that case, because you couldn't predict which actors could be the ones terminating one that was given the :terminate message; similar to how you could know that if there are two light switches that toggle one bulb, then its state is effected only by one of those two switches.

edit, in case amateur grammar police read along: one bulb can be affected by multiple switches, yet have its voltage effected by touching any single switch. this is a common gimmick indispensible for corridor lighting!

Right, but that's beyond the scope of the actor. In Chipi project this is solved by being able to setup rules.