| Index: samples/actors/README
|
| diff --git a/samples/actors/README b/samples/actors/README
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d9af7dbb6df9241dd76b96f0909a852f9be7c693
|
| --- /dev/null
|
| +++ b/samples/actors/README
|
| @@ -0,0 +1,188 @@
|
| +== Introduction ==
|
| +
|
| +The Actor model is a model of concurrent computation for distributed systems.
|
| +An actor system consists of a number of concurrent and autonomous entities
|
| +called actors. An actor has its own thread of control and state and is the
|
| +unit of concurrency in the actor model. The state of actor is encapsulated
|
| +and is not shared. Actors communicate using asynchronous message passing.
|
| +Each actor updates its own local state by processing messages that it receives
|
| +in its mailbox.
|
| +
|
| +Dart is the Google’s new language for web programming which features Isolates.
|
| +Isolates provide a message passing model for programming in a non-shared memory
|
| +setting. Here, we have an Actor framework developed on top of isolates as an
|
| +alternative to using isolates directly. The goals of this framework are:
|
| +
|
| +1- Easier concurrent programming in Dart via a familiar syntax inspired by Scala
|
| +and Erlang
|
| +2- Cheap creation of lightweight concurrent entities (actors) for responsiveness
|
| +3- Providing an API for accessing DOM from within a remote isolate
|
| +
|
| +
|
| +== Getting Started ==
|
| +
|
| +An actor is defined by a class. It is required that this class extends the
|
| +"Actor" class. The Actor class handles all the mechanics for sending and serving
|
| +messages and creating new actors.
|
| +
|
| +class HelloWorld extends Actor {
|
| + HelloWorld() : super() {
|
| + // ...
|
| + }
|
| +}
|
| +
|
| +Message handlers are defined inside the constructor's body.
|
| +
|
| +class HelloWorld extends Actor {
|
| + HelloWorld() : super() {
|
| +
|
| + // a message handler for "say hello" message
|
| + on["say hello"] = (String who) {
|
| + ui.send("print", ["Hello $who!"]);
|
| + };
|
| +
|
| + // a message handler for "say goodbye" message
|
| + on["say goodbye"] = (String who) {
|
| + ui.send("print", ["Bye $who!"]);
|
| + };
|
| +
|
| + }
|
| +}
|
| +
|
| +Every actor has access to the 'ui' actor for printing on the console. One can
|
| +print something on the console by sending "print" message to the ui actor:
|
| +
|
| + ui.print("A string");
|
| +
|
| +Note that the print function is only a syntactic sugar for:
|
| +
|
| + ui.send("print", ["A string"]);
|
| +
|
| +
|
| +== Actor Discovery and Message Passing ==
|
| +
|
| +No one can get a reference to an actor object. Actors are only accessible
|
| +through their identity which can be used to send messages to the actor.
|
| +How to send a message to an actor using its id?
|
| +
|
| + id.send("message name", [parameters]);
|
| +
|
| +Running on the dart VM, parameters can be everything but closures.
|
| +
|
| +In order to become known to other actors, one can send its own id to them. An
|
| +actor can access its own id using 'me' and can send it as a parameter.
|
| +
|
| + anotherActorId.send("contact me", [me]);
|
| +
|
| +One can only send a message to self using 'me':
|
| +
|
| + me.send("message to self", [parameters]);
|
| +
|
| +
|
| +== Creating Actors ==
|
| +
|
| +ActorManager is responsible for creating actors. The first actor is created by
|
| +actor manager from the main function of the application. For instance, for the
|
| +HelloWorld example, the main functions looks like the following:
|
| +
|
| +main() {
|
| + ActorManager manager = new ActorManager(1);
|
| + manager.create(const HelloWorldFactory(),
|
| + "say hello", ["World"]);
|
| +}
|
| +
|
| +class HelloWorldFactory implements ActorFactory {
|
| + const HelloWorldFactory();
|
| + Actor create() => new HelloWorld();
|
| +}
|
| +
|
| +Let's step through the main function. The following line will create an actor
|
| +manager:
|
| +
|
| + ActorManager manager = new ActorManager(1);
|
| +
|
| +The parameter sent to the constructor is the number of background isolates used
|
| +to schedule actors. In the above example it is one.
|
| +
|
| +The next line will ask actor manager to create an actor using the specified
|
| +factory object:
|
| +
|
| + manager.create(const HelloWorldFactory(),
|
| +
|
| +The second and third parameters to the create function are the initial message
|
| +and parameters that must be sent to the actor upon creation:
|
| +
|
| + manager.create(const HelloWorldFactory(),
|
| + "say hello", ["World"]);
|
| +
|
| +
|
| +Because of the lack of reflection (at the time of writing the framework) in
|
| +Dart, there should be an actor factory for each actor.
|
| +
|
| +An actor creates other actor by calling a create function. This function is
|
| +defined in the "Actor" class and it has the same parameters as mentioned above.
|
| +
|
| +
|
| +== Request and Response ==
|
| +
|
| +In order to get a response back for a message sent to another actor, you can use
|
| +a Reply object. The Reply object encapsulates the way a response should be sent
|
| +back to an actor. For instance, in the following example a client actor needs
|
| +the fibonacci value of 100. It sends a message ("fibonacci") to a calculator
|
| +actor and includes the number and a Reply object. Reply object takes two
|
| +parameters. The first one indicates to whom the message must be sent and the
|
| +second one indicates what message must be used to send the response back.
|
| +
|
| +///// Client Actor
|
| +
|
| +on["some message"] = () {
|
| + num n = 100;
|
| + calculatorActor
|
| + .send("fibonacci",
|
| + [n, new Reply(me, "fib-result")]);
|
| +};
|
| +
|
| +on["fib-result"] = (num fibOfN) {
|
| + ...
|
| +};
|
| +
|
| +///// Calculator Actor
|
| +
|
| +on["fibonacci"] = (num n, Reply reply) {
|
| + reply.response([fib(n)]);
|
| +};
|
| +
|
| +In the above example the, client must have a named message handler,
|
| +"fib-result", in order to handle the result. One can use messageback to create
|
| +an unnamed message handler.
|
| +
|
| +
|
| +///// Client Actor
|
| +
|
| +on["some message"] = () {
|
| + num n = 100;
|
| + calculatorActor
|
| + .send("fibonacci",
|
| + [n,
|
| + messageback((num fibOfN) {
|
| + ...
|
| + };
|
| + )]);
|
| +};
|
| +
|
| +
|
| +== Programming with Actors ==
|
| +
|
| +When you are programming with actors, you can either program for web or
|
| +terminal. If you are programming for web you will need to import
|
| +'actors-web.dart' from core. You also will need to have a version of browser in
|
| +which Dart VM is enabled. In case you only want to write a console application,
|
| +you will need to import 'actors-term.dart' from core.
|
| +
|
| +
|
| +== Known Issues ==
|
| +
|
| +The current version of this framework does not work with frog and/or dartc.
|
| +Applications written using this framework run with Dart VM (command line or a
|
| +Dart enabled browser).
|
| +
|
|
|