Nit Actor Model
This group introduces the
actors module which contains the abstraction of a Nit Actor Model,
based on Celluloid (https://github.com/celluloid/celluloid).
What is an actor ?
An actor is an entity which receives messages and does some kind of computation based on it. An actor has a mailbox in which it receives its messages, and process them one at a time.
actors module introduces the annotation
actor which is to be used on classes.
This annotation transform a normal Nit class into an actor.
In practice, it adds a new property
async to the annotated class.
async on your annotated class, this means that you want your calls to be asynchronous,
executed by the actor.
For instance, if you call
foo doesn't have a return value, it will send
a message to the mailbox of the actor attached to
a which will process it asynchronously.
On the other hand, if you call
bar returns an
Int, it will still send
a message to the actor, but you'll get a
Future[Int] to be able to retrieve the value.
join on the future, the calling thread will wait until the value of the future is set.
When you annotate a class with
actor and create an instance of it with
new, the actor is not
automatically created (which means you can completely skip the use of the actors if you
don't need them for a specific program).
async added property is actually created lazily when you use it.
Actors are not automatically garbage collected, but you have solutions to terminate them
if you need to. For this, you need to use the
async property of your annotated class :
async.terminatesends a shutdown message to the actor telling him to stop, so he'll finish processing every other messages in his mailbox before terminating properly. Every other messages sent to this actor after he received the shutdown message won't be processed.
async.terminate_nowsends a shutdown message too, but this time it places it first, so if the actor is processing one message now, the next one will be the shutdown message, discarding every messages in its mailbox.
async.wait_terminationwait for the actor to terminate properly. This call is synchronous.
async.kill. If you really need this actor to stop, without any regards of what he was doing or in which state he'll leave the memory, you can with this call. it's synchronous but not really blocking, since it's direcly canceling the native pthread associated to the actor.
For now, there isn't any mecanism to recreate and actor after it was terminated. Sending messages after terminating it results in unspecified behaviour.
Waiting for all actors to finish processing
Let's imagine you create a whole bunch of actors and make them do things asynchronously from the main thread. You don't want your program to exit right after giving work to your actors. To prevent that, we added a mecanism that waits before all your actors finished all their messages before quitting.
It's materialized by the
active_actors property added to
Sys which is a
In short, the
is_empty method on this list is blocking until the list is effectively empty.
When every actors finished working, and we're sure they won't even send another message to another
active_actors is empty.
You can use this property as a mean of synchronisation in some specific cases (for example if you're using actors for fork/join parallelism instead of concurrency).
You can find example of differents small programs implemented with Nit actors in the
directory. For a really simple example, you can check
- actors: Nit Actor Model (lib/actors)
- actors: Abstraction of the actors concepts (lib/actors/actors.nit)
- examples (lib/actors/examples)
- agent_simulation (lib/actors/examples/agent_simulation)
- actors_agent_simulation: This file is generated by nitactors (threaded version) (lib/actors/examples/agent_simulation/actors_agent_simulation.nit)
- actors_simple_simulation: This file is generated by nitactors (threaded version) (lib/actors/examples/agent_simulation/actors_simple_simulation.nit)
- agent_simulation: a "Framework" to make Multi-Agent Simulations in Nit (lib/actors/examples/agent_simulation/agent_simulation.nit)
- simple_simulation: Using
agent_simulationby refining the Agent class to make (lib/actors/examples/agent_simulation/simple_simulation.nit)
- chameneos-redux (lib/actors/examples/chameneos-redux)
- actors_chameneosredux: This file is generated by nitactors (threaded version) (lib/actors/examples/chameneos-redux/actors_chameneosredux.nit)
- chameneosredux: Example implemented from "The computer Language Benchmarks Game" - Chameneos-Redux (lib/actors/examples/chameneos-redux/chameneosredux.nit)
- fannkuchredux (lib/actors/examples/fannkuchredux)
- actors_fannkuchredux: This file is generated by nitactors (threaded version) (lib/actors/examples/fannkuchredux/actors_fannkuchredux.nit)
- fannkuchredux: Example implemented from "The computer Language Benchmarks Game" - Fannkuch-Redux (lib/actors/examples/fannkuchredux/fannkuchredux.nit)
- mandelbrot (lib/actors/examples/mandelbrot)
- actors_mandelbrot: This file is generated by nitactors (threaded version) (lib/actors/examples/mandelbrot/actors_mandelbrot.nit)
- mandelbrot: Example implemented from "The computer Language Benchmarks Game" - Mandelbrot (lib/actors/examples/mandelbrot/mandelbrot.nit)
- simple (lib/actors/examples/simple)
- actors_simple: This file is generated by nitactors (threaded version) (lib/actors/examples/simple/actors_simple.nit)
- simple: A very simple example of the actor model (lib/actors/examples/simple/simple.nit)
- thread-ring (lib/actors/examples/thread-ring)
- actors_thread_ring: This file is generated by nitactors (threaded version) (lib/actors/examples/thread-ring/actors_thread_ring.nit)
- thread_ring: Example implemented from "The computer Language Benchmarks Game" - Thread-Ring (lib/actors/examples/thread-ring/thread_ring.nit)
- agent_simulation (lib/actors/examples/agent_simulation)