lux/concurrency/actor
The actor model of concurrency.
Types
Actor
An actor, defined as all the necessities it requires.
(type: (Actor s m)
{#mailbox (lux/concurrency/stm;Var m)
#kill-signal (lux/concurrency/promise;Promise lux;Unit)
#obituary (lux/concurrency/promise;Promise [(lux;Maybe lux;Text) s (lux;List m)])})
Behavior
An actor's behavior when messages are received.
(type: (Behavior s m)
{#step (-> (Actor s m) m s (lux/concurrency/promise;Promise (lux/data/error;Error s)))
#end (-> (lux;Maybe lux;Text) s (lux/concurrency/promise;Promise lux;Unit))})
Macros
actor:
## Allows defining an actor, with a pice of state and a set of methods that can be called on it.
## A method can access the actor's state through the *state* variable.
## A method can also access the actor itself through the *self* variable.
## A method may succeed or fail (in case of failure, the actor dies). This is handled through the Either type.
## A method's output must be a promise containing a 2-tuple with the updated state and a return value.
## All methods are run implicitly within the Promise monad.
(actor: #export Adder
Int
(method: (count! [to-add Int])
[Int Int]
(if (i.>= 0 to-add)
(let [new-state (i.+ to-add *state*)]
(wrap (#lux;Right[new-state [*state* new-state]])))
(wrap (#lux;Left"Can't add negative numbers!")))))
Values
(alive? actor)
(All [a b] (-> (Actor a b) lux;Bool))
(keep-alive init behavior)
Given initial-state and a behavior, spawns an actor that will reboot if it dies of errors.
However, if it is killed, it won't re-spawn.
(All [a b] (-> a (Behavior a b) (lux/codata/io;IO (Actor a b))))
poison
Immediately kills the given actor (if it's not already dead).
(All [a b] (-> (Actor a b) (lux/codata/io;IO lux;Bool)))
(send message actor)
Communicate with an actor through message passing.
(All [a b] (-> b (Actor a b) (lux/concurrency/promise;Promise lux;Bool)))
(spawn init behavior)
Given a behavior and initial state, spawns an actor and returns it.
(All [a b] (-> a (Behavior a b) (lux/codata/io;IO (Actor a b))))