mdbergmann / cl-gserver

Sento - Actor framework featuring actors and agents for easy access to state and asynchronous operations.

Home Page:https://mdbergmann.github.io/cl-gserver/index.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Inquiry: Do actors have local state?

lamuswawir opened this issue · comments

I have been trying to setf state for a single actor, however doing so updates the special variable state. And actors created after will have that the same state. I have seen that agents are designed for state management. Is there a built in way to update state for a single actor?

Actors are generally made to maintain state. And so here.
The normal use-case is that you generate an actor with some state (using key parameter :state) and change (setf) that state only in the receive function via special variable *state*. Because that guaranties thread-safety. This state is then unique to only this actor. The case where you share state across multiple actors is also possible but not a common case.
Agents enforce this behavior a bit more formally. But eventually that's also how actors are to be used.

Maybe I misunderstood what you asked though. :)

I was using it incorrectly. This is what I have found: when I initialise state via :state, the value is fixed when I call (act-cell:state actor) and doesn't change even after (setf *state* new-state). However, when I return the *state* from within the :receive lambda, I get the new state. At first I thought calling (act-cell:state actor) would return the updated state.

The bug was because I was doing (setf state new-state), not using the ear muffs. state was shared across all actors. (I guess I arrived at the situation you described through a bug!)

Thank you. And thank you for the good work!

The state should change via (setf *state* new-state*) when called (and only when called) from within the init or receive function, because only there *state* is supplied correctly.
See actor-test.lisp - test make-actor--with-msgbox.

The return value of receive is only used when doing ask-s, the synchronous ask.
When using ?/ask then the return value is ignored because it's all async.

Okay. I have solved the issue with ask-s.

Thank you.