perform:withArguments: in order to provide a convenient way of
sending requests to
Switching between an Actor and its ActorProxy
Actor has exactly one
ActorProxy, and every
associated with exactly one
ActorProcesses also have proxies: see the comment
ActorProcess >> #proxy.
ActorProxy have methods
actor always returns the
Actor of a matched pair; calling
proxy always returns the
anActor actor == anActor. anActor proxy actor == anActor. anActorProxy proxy == anActorProxy. anActorProxy actor proxy == anActorProxy.
ActorProxy and dependents
Each proxy implements
asynchronously forwarding them to its backing actor. Similarly, each
proxy forwards calls to
update:with: to its backing
ActorProxy instances are intended to be long lived—at least as long
lived as their backing actor.
For this reason,
ActorProxy inherits from
Object, including all
the behavior of
Object. This causes quite a bit of clutter in the
For example, consider calling
windowTitle on an
The intention here is for the request to be forwarded on to the
backing actor’s behavior object. Unfortunately,
windowTitle. The request will thus be answered locally at the proxy,
without ever being sent on to its actor.
To avoid this problem, proxy objects allow creation of transient proxy objects which have a much smaller interface and can therefore easily forward more requests than an ordinary proxy can:
myProxy async windowTitle. myProxy sync windowTitle. myProxy blocking windowTitle.
The three variants,
blocking are discussed
Think twice before storing a
TransientActorProxy instance in a
TransientActorProxy inherits from
Object. While the interface of
ProtoObject is small, it is so
small that transient proxies do not play nicely with the inspector,
the explorer and other tools in the development environment. This is
why they should be considered “transient” or temporary.
The three methods
blocking on an
instance each return instances of a distinct subclass of
Each allows a distinct interaction pattern:
AsyncTransientActorProxyoffers asynchronous (one-way) messaging;
SyncTransientActorProxyoffers request/reply/error messaging, using Promises to mediate between caller and callee; and
SyncTransientActorProxy, but hides the promises away, waiting for a reply at the time the call is made.
someProxy async notifyOfSomeEvent: details
The result of
ActorProxy >> #async is an
Messages sent this way do not allocate any promises, and always return
(someProxy sync doSomethingWith: anArgument) >>= [:result | self handleResult: result] bindActor. self whileWeWaitDoSomethingElse.
The result of
ActorProxy >> #sync is a
Like messages sent to a plain old
ActorProxy, messages sent this way
allocate and immediately return
These promises are eventually resolved or rejected according to the code executing at the remote actor.
result := someProxy blocking doSomethingWith: anArgument. self handleResult: result. self nowDoSomethingElse.
The result of
ActorProxy >> #blocking is a
BlockingTransientActorProxy. Messages sent this way internally
ActorPromise, but do not expose it: instead, they
immediately wait for the promise to be resolved or rejected. These
messages eventually either return a value or signal
There are circumstances where a
blocking call will not return, such
as when the callee “detaches”,
but never replies to, the request it receives.