User Tools

Site Tools


at:tutorial:actors

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
at:tutorial:actors [2007/07/18 09:29] elisagat:tutorial:actors [2007/07/18 10:43] elisag
Line 14: Line 14:
 Generally speaking, an active object is an object that encapsulates its own thread of control. An active object also has a message queue or mailbox from which it processes incoming messages. Each message is processed sequentially. An active object responds to an incoming message by invoking the method corresponding to the message. The method is executed by the active object's own thread. Because of this sequential processing of incoming messages, race conditions cannot occur on the internal state of an active object. Objects communicate with active objects by sending them messages //asynchronously//: the messages are enqueued in the receiver's message queue, rather than being invoked immediately. Generally speaking, an active object is an object that encapsulates its own thread of control. An active object also has a message queue or mailbox from which it processes incoming messages. Each message is processed sequentially. An active object responds to an incoming message by invoking the method corresponding to the message. The method is executed by the active object's own thread. Because of this sequential processing of incoming messages, race conditions cannot occur on the internal state of an active object. Objects communicate with active objects by sending them messages //asynchronously//: the messages are enqueued in the receiver's message queue, rather than being invoked immediately.
  
-===== Actors and Far References =====+===== AmbientTalk Actors and Far References =====
  
 In AmbientTalk, concurrency is spawned by creating actors: each actor is an autonomous processor. AmbientTalk's actors are based on the [[Wp>E_programming_language|vat model]] of the [[http://www.erights.org|E programming language]]. In AmbientTalk, an actor consists of a message queue (to store incoming messages), a thread of control (to execute the incoming messages) and a number of regular objects that are said to be //hosted// by the actor. In AmbientTalk, concurrency is spawned by creating actors: each actor is an autonomous processor. AmbientTalk's actors are based on the [[Wp>E_programming_language|vat model]] of the [[http://www.erights.org|E programming language]]. In AmbientTalk, an actor consists of a message queue (to store incoming messages), a thread of control (to execute the incoming messages) and a number of regular objects that are said to be //hosted// by the actor.
Line 37: Line 37:
 </note> </note>
  
-The figure below summarizes AmbientTalk's concurrency model where actors are represented as communicating event loops. The dotted lines represent the event loop threads of the actors which perpetually take messages from their message queue and synchronously execute the corresponding methods on the actor's owned objects. An event loop thread never //escapes// its actor boundary. When communication with an object in another actor is required, a message is sent asynchronously via a far reference to the object. For example, as shown in the figure, when A sends a message to B, the message is enqueued in the message queue of B's actor which eventually processes it.+The figure below summarizes AmbientTalk's concurrency model where actors are represented as communicating event loops. The dotted lines represent the actor'event loop threads which perpetually take messages from their message queue and synchronously execute the corresponding methods on the actor's owned objects. Note that an event loop thread never //escapes// its actor boundary: when communication with an object in another actor is required, a message is sent asynchronously via a far reference to the object. For example, as shown below, when A sends a message to B, the message is enqueued in the message queue of B's actor which eventually processes it.
  
 {{ :at:tutorial:concurrencymodel.png?450 |AmbientTalk actors as communicating event loops }} {{ :at:tutorial:concurrencymodel.png?450 |AmbientTalk actors as communicating event loops }}
Line 98: Line 98:
 The parameter passing semantics defined above rule out any possibility for an object to be passed by copy. The reason for this semantics is that objects encapsulate a lexical scope, and parameter passing an object by copy would require the entire lexical scope to be parameter-passed as well. The parameter passing semantics defined above rule out any possibility for an object to be passed by copy. The reason for this semantics is that objects encapsulate a lexical scope, and parameter passing an object by copy would require the entire lexical scope to be parameter-passed as well.
  
-To enable objects to be passed by copy between actors, a special type of objects is introduced. These objects are called **isolates** because they are //isolated// from their lexical scope. Continuing our previous example, imagine we want our calculator to work with complex numbers, which are typically objects that one would want to pass by copy. We can define complex numbers as isolate objects as follows:+To enable objects to be passed by copy between actors, a special type of objects is introduced. These objects are called **isolates** because they are //isolated// from their surrounding lexical scope. Continuing our previous example, imagine we want our calculator to work with complex numbers, which are typically objects that one would want to pass by copy. We can define complex numbers as isolate objects as follows:
  
 <code> <code>
Line 137: Line 137:
 </code> </code>
  
-<note important+<note warning
-A word of warning: isolates are objects that are copied freely between actors. As a result, they should be objects whose actual object identity is of little importance. Usually, the identity of by-copy objects is determined by the value of some of the object's fields. Therefore, it is good practice to override the ''=='' method on isolates to compare isolates based on their semantic identity, rather than on their object identity. For example, equality for complex numbers should be defined as:+A word of warning: isolates are objects that are (deep) copied freely between actors. As a result, they should be objects whose actual object identity is of little importance. Usually, the identity of by-copy objects is determined by the value of some of the object's fields. Therefore, it is good practice to override the ''=='' method on isolates to compare isolates based on their semantic identity, rather than on their object identity. For example, equality for complex numbers should be defined as:
 <code> <code>
 def ==(other) { def ==(other) {
Line 146: Line 146:
 </note> </note>
  
-It is important to note that an isolate has no access whatsoever to its encompassing scope. The following code results in an exception:+As already explained, an isolate has no access whatsoever to its encompassing scope. Hence, the following code results in an exception:
  
 <code> <code>
Line 159: Line 159:
 </code> </code>
  
-Sometimes it is useful to initialize an isolate with the values of lexically visible variables. In that case, AmbientTalk allows the programmer to specify which lexical variables should be //copied into// the isolate itself, such that the isolate has its own, local copy of the variable. Lexical variables that need to be copied like this are specified as formal parameters to the closure passed to the ''isolate:'' primitive, as follows:+However, sometimes it is useful to initialize an isolate with the values of lexically visible variables. To this end, AmbientTalk allows the programmer to specify which lexical variables should be //copied into// the isolate itself, such that the isolate has its own, local copy of the variable. Lexical variables that need to be copied like this are specified as formal parameters to the closure passed to the ''isolate:'' primitive, as follows:
  
 <code> <code>
Line 172: Line 172:
 ===== Futures ===== ===== Futures =====
  
-As you may have noticed previously, asynchronous message sends do not return any value (that is, they return ''nil''). Quite often, the developer is required to work around this lack of return values by means of e.g. explicit customer objects, as shown previously. This, however, leads to less expressive, more difficult to understand code, where the control flow quickly becomes implicit.+As you may have noticed previously, asynchronous message sends do not return any value (that is, they return ''nil''). Quite often, the developer is required to work around this lack of return values by means of e.g. explicit customer objects, as shown previously in the calculator example. This, however, leads to less expressive, more difficult to understand code, where the control flow quickly becomes implicit.
  
 ==== The Concept ==== ==== The Concept ====
  
-The most well-known language feature to reconcile return values with asynchronous message sends is the notion of a [[Wp>Future_(programming)|future]]. Futures are objects that represent return values that may not yet have been computed. Once the asynchronously invoked method has completed, the future is replaced with the actual return value, and objects that referred to the future transparently refer to the return value.+The most well-known language feature in concurrent and distributed languages (for example, in ABCL, the actor-based concurrent language) to reconcile return values with asynchronous message sends is the notion of a  [[Wp>Future_(programming)|future]]. Futures are also commonly known by the name of //promises// (this is how they are called in the [[http://www.erights.org|E language]] and in Argus). Futures are objects that represent return values that may not yet have been computed. Once the asynchronously invoked method has completed, the future is replaced with the actual return value, and objects that referred to the future transparently refer to the return value.
  
 Using futures, it is possible to re-implement the previous example of requesting our calculator actor to add two numbers as follows: Using futures, it is possible to re-implement the previous example of requesting our calculator actor to add two numbers as follows:
Line 186: Line 186:
 ==== Enabling futures ==== ==== Enabling futures ====
  
-Futures are a frequently recurring language feature in concurrent and distributed languages (for example, in ABCL, the actor-based concurrent language). They are also commonly known by the name of //promises// (this is how they are called in the [[http://www.erights.org|E language]] and in Argus). In AmbientTalk, futures are not native to the language. However, because of AmbientTalk's reflective infrastructure, it is possible to build futures on top of the language. The system library shipped with AmbientTalk contains exactly this: a reflective implementation that adds futures to the language kernel. This implementation can be found in the file ''at/lang/futures.at''.+In AmbientTalk, futures are not native to the language. However, because of AmbientTalk's reflective infrastructure, it is possible to build futures on top of the language. The system library shipped with AmbientTalk contains exactly this: a reflective implementation that adds futures to the language kernel. This implementation can be found in the file ''at/lang/futures.at''.
  
 To enable futures, it suffices to import the futures module and to enable it, as follows: To enable futures, it suffices to import the futures module and to enable it, as follows:
at/tutorial/actors.txt · Last modified: 2020/02/05 21:26 by elisag