Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 == Introduction == | |
| 2 | |
| 3 Actor model is a model of concurrent computation for distributed systems. | |
|
vsm
2011/12/16 20:39:36
Actor model -> The Actor model
amshali
2011/12/16 21:22:30
Done.
| |
| 4 An actor system consists of a number of concurrent and autonomous entities | |
| 5 called actors. An actor has its own thread of control and state and is the | |
| 6 unit of concurrency in the actor model. The state of actor is encapsulated | |
| 7 and is not shared. Actors communicate using asynchronous message passing. | |
| 8 Each actor updates its own local state by processing messages that it receives | |
| 9 in its mailbox. | |
| 10 | |
| 11 Dart is the Google’s new language for web programming which features Isolates. | |
| 12 Isolates provide a message passing model for programming in a non-shared memory | |
| 13 setting. Here, we have an Actor framework developed on top of isolates as an | |
| 14 alternative to using isolates directly. The goals of this framework are: | |
| 15 | |
| 16 1- Easier concurrent programming in Dart via a familiar syntax inspired by Scala | |
| 17 and Erlang | |
| 18 2- Cheap creation of lightweight concurrent entities (actors) for responsiveness | |
| 19 3- Providing an API for accessing DOM from within a remote isolate | |
| 20 | |
| 21 | |
| 22 == Getting Started == | |
| 23 | |
| 24 An actor is defined by a class. It is required that this class extends the | |
| 25 "Actor" class. The Actor class handles all the mechanics for sending and serving | |
| 26 messages and creating new actors. | |
| 27 | |
| 28 class HelloWorld extends Actor { | |
| 29 HelloWorld() : super() { | |
| 30 // ... | |
| 31 } | |
| 32 } | |
| 33 | |
| 34 Message handlers are defined inside the constructor's body. | |
| 35 | |
| 36 class HelloWorld extends Actor { | |
| 37 HelloWorld() : super() { | |
| 38 | |
| 39 // a message handler for "say hello" message | |
| 40 on["say hello"] = (String who) { | |
| 41 ui.send("print", ["Hello $who!"]); | |
| 42 }; | |
| 43 | |
| 44 // a message handler for "say goodbye" message | |
| 45 on["say goodbye"] = (String who) { | |
| 46 ui.send("print", ["Bye $who!"]); | |
| 47 }; | |
| 48 | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 Every actor has access to the 'ui' actor for printing on the console. One can | |
| 53 print something on the console by sending "print" message to the ui actor: | |
| 54 | |
| 55 ui.print("A string"); | |
| 56 | |
| 57 Note that the print function is only a syntactic sugar for: | |
| 58 | |
| 59 ui.send("print", ["A string"]); | |
| 60 | |
| 61 | |
| 62 == Actor Discovery and Message Passing == | |
| 63 | |
| 64 No one can get a reference to an actor object. Actors are only accessible | |
| 65 through their identity which can be used to send messages to the actor. | |
| 66 How to send a message to an actor using its id? | |
| 67 | |
| 68 id.send("message name", [parameters]); | |
| 69 | |
| 70 Running on the dart VM, parameters can be everything but closures. | |
| 71 | |
| 72 In order to become known to other actors, one can send its own id to them. An | |
| 73 actor can access its own id using 'me' and can send it as a parameter. | |
| 74 | |
| 75 anotherActorId.send("contact me", [me]); | |
| 76 | |
| 77 One can only send a message to self using 'me': | |
| 78 | |
| 79 me.send("message to self", [parameters]); | |
| 80 | |
| 81 | |
| 82 == Creating Actors == | |
| 83 | |
| 84 ActorManager is responsible for creating actors. The first actor is created by | |
| 85 actor manager from the main function of the application. For instance, for the | |
| 86 HelloWorld example, the main functions looks like the following: | |
| 87 | |
| 88 main() { | |
| 89 ActorManager manager = new ActorManager(1); | |
| 90 manager.create(const HelloWorldFactory(), | |
| 91 "say hello", ["World"]); | |
| 92 } | |
| 93 | |
| 94 class HelloWorldFactory implements ActorFactory { | |
| 95 const HelloWorldFactory(); | |
| 96 Actor create() => new HelloWorld(); | |
| 97 } | |
| 98 | |
| 99 Let's step through the main function. The following line will create an actor | |
| 100 manager: | |
| 101 | |
| 102 ActorManager manager = new ActorManager(1); | |
| 103 | |
| 104 The parameter sent to the constructor is the number of background isolates used | |
| 105 to schedule actors. In the above example it is one. | |
| 106 | |
| 107 The next line will ask actor manager to create an actor using the specified | |
| 108 factory object: | |
| 109 | |
| 110 manager.create(const HelloWorldFactory(), | |
| 111 | |
| 112 The second and third parameters to the create function are the initial message | |
| 113 and parameters that must be sent to the actor upon creation: | |
| 114 | |
| 115 manager.create(const HelloWorldFactory(), | |
| 116 "say hello", ["World"]); | |
| 117 | |
| 118 | |
| 119 Because of the lack of reflection (at the time of writing the framework) in | |
| 120 Dart, there should be an actor factory for each actor. | |
| 121 | |
| 122 An actor creates other actor by calling a create function. This function is | |
| 123 defined in the "Actor" class and it has the same parameters as mentioned above. | |
| 124 | |
| 125 == Request and Response == | |
| 126 | |
| 127 In order to get a response back for a message sent to another actor, you can use | |
| 128 a Reply object. The Reply object encapsulates the way a response should be sent | |
| 129 back to an actor. For instance, in the following example a client actor needs | |
| 130 the fibonacci value of 100. It sends a message ("fibonacci") to a calculator | |
| 131 actor and includes the number and a Reply object. Reply object takes two | |
| 132 parameters. The first one indicates to whom the message must be sent and the | |
| 133 second one indicates what message must be used. | |
| 134 | |
| 135 ///// Client Actor | |
| 136 | |
| 137 on["some message"] = () { | |
| 138 num n = 100; | |
| 139 calculatorActor | |
| 140 .send("fibonacci", | |
| 141 [n, new Reply(me, "fib-result")]); | |
| 142 }; | |
| 143 | |
| 144 on["fib-result"] = (num fibOfN) { | |
| 145 ... | |
| 146 }; | |
| 147 | |
| 148 ///// Calculator Actor | |
| 149 | |
| 150 on["fibonacci"] = (num n, Reply reply) { | |
| 151 reply.response([fib(n)]); | |
| 152 }; | |
| 153 | |
| 154 In the above example the, client must have a named message handler, | |
| 155 "fib-result", in order to handle the result. One can use messageback to create | |
| 156 an unnamed message handler. | |
| 157 | |
| 158 | |
| 159 ///// Client Actor | |
| 160 | |
| 161 on["some message"] = () { | |
| 162 num n = 100; | |
| 163 calculatorActor | |
| 164 .send("fibonacci", | |
| 165 [n, | |
| 166 messageback((num fibOfN) { | |
| 167 ... | |
| 168 }; | |
| 169 )]); | |
| 170 }; | |
| 171 | |
| 172 == Programming with Actors == | |
| 173 | |
| 174 When you are programming with actors, you can either program for web or | |
| 175 terminal. If you are programming for web you will need to import | |
| 176 'actors-web.dart' from core. You also will need to have a version of browser in | |
| 177 which Dart VM is enabled. In case you only want to write a console application, | |
| 178 you will need to import 'actors-term.dart' from core. | |
| 179 | |
| 180 | |
| OLD | NEW |