This document describes cell 0.0. For development docs, go here.
Hello World¶
Here we will demonstrate the main cell features starting with a simple Hello World example. To understand what is going on, we will break the example into pieces.
Defining an actor¶
Actors are implemented by extending the Actor
class and then defining a series of supported methods.
The supported methods should be encapsulated in the Actor’s internal state
class.
Our first actor implements one method called greet.
from cell.actors import Actor
class GreetingActor(Actor):
class state:
def greet(self, who='world'):
print 'Hello %s' % who
Starting an actor¶
Cell targets distributed actors management. Therefore, creating an actor means spawning an actor consumer remotely by sending a command to a celery worker agent. That is why before spawning an actor, you need to have a celery worker running:
$ celery worker
Actors are created via spawn()
method, called on an instance of dAgent
(distributed agent).
Agents are components responsible for creating and stopping actors on celery workers.
Each celery worker has embedded agent component dAgent
(distributed agent) listening for commands.
spawn()
is invoked with a class of type Actor
or its derivative
and starts an actor of that type remotely (in the celery worker).
The method returns a proxy (an instance of ActorProxy
) for the remotely started actor.
The proxy holds the unique identifier, which ensures the messages can be delivered unambiguously to the same remote actor.
The code below starts a GreetingActor
and then invokes its py:meth:greeting method.
from cell.agents import dAgent
from kombu import Connection
connection = Connection()
# STEP 1: Create an agent
agent = dAgent(connection)
# STEP 2: Pass the actor type to spawn method
greeter = agent.spawn(GreetingActor)
# STEP 3: Use actor proxy to call methods on the remote actor
greeter.send('greet')
Calling a method¶
The cell actor model comes with few build-in delivery policies. Here we demonstrate direct delivery - the message is send to a particular actor instance. (Look at the end of the section for the other delivery options.)
actor.send('greet')
The greet()
method has been executed and you can verify that by looking at the workers console output.
The remote actor of type GreetingActor you created earlier handle the method.
The message ‘Hello world’ should be printed on the celery worker console.
Note that the call is asynchronous and since ‘great’ is a void method no result will be returned.
For getting results back and invoking methods synchronously check Getting a result back section
- The basic Actor API expose three more methods for sending a message:
send()
- sends to a particular actor instancethrow()
- sends to an actor instance of the same typescatter()
- sends to all actor instances of the same type
For more information on the above options, see the Delivery options section
Calling a method with parameters¶
Here is an example how to call the method greet()
with an argument who
actor.send('greet', {'who':'everyone'})
Getting a result back¶
Let’s add another method to the GreetingActor
class
how_are_you()
that returns a result.
from cell.actors import Actor
class GreetingActor(Actor):
class state:
def greet(self, who='world'):
print 'Hello %s' % who
def how_are_you(self):
return 'Fine!'
We can get the result in two ways:
- using a blocking call (set the nowait parameter to True), it blocks the execution until a result is delivered or a timeout is reached:
result = actor.send('greet', {'who':'everyone'}, nowait=True)
d.. warning:: If you are using blocking calls, greenlets should be enabled in the celery worker:
Greenlets can be enabled either by using eventlet or using gevent:
>>> celery worker -P eventlet -c 100
or
>>> celery worker -P gevent -c 100
You can read more about concurrency in celery in here
- using a non-blocking call (set the nowait parameter to False, the default), it returns an an
AsyncResult
instance.
AsyncResult
can be used to check the state of the result, get the return value or if the method failed, the exception and traceback).
result = actor.send('greet', {'who':'everyone'}, nowait=False)
The result()
returns the result if it is ready or wait for the result to complete
result = actor.send('greet', {'who':'everyone'}, nowait=False)
print result.result
See cell.result for the complete result object reference.
Stopping an actor¶
We can stop an actor if we know its id.
agent.kill(actor.id)
agents.dAgent.kill()
is a broadcast command sent to all agents.
If an agents doesn’t have in its registry the given actor.id, it will dismiss the command,
otherwise it will gently kill the actor and delete it from its registry.
Where to go from here¶
If you want to learn more you should explore the examples in the examples
module in the cell codebase
and/or study the User Guide.