Subsections

4 The candygram module

The candygram module exports the following functions, classes, constants, and exceptions. Since the name candygram is a bit long, you would typically import the module in one of the following ways:

>>> from candygram import *
or
>>> import candygram as cg

4.1 Functions

spawn( func[, args...][, _processClass=Process])
Create a new concurrent process by calling the function func with the args argument list and return the resulting Process instance. When the function func returns, the process terminates. Raises a 'badarg' ExitError if func is not callable().

If you define a subclass of Process, you can instruct the spawn() function to create an instance of that class by passing the class with the optional _processClass keyword argument.

link( proc)
Create a link to the process proc, if there is not such a link already. If a process attempts to create a link to itself, nothing is done. Raises a 'badarg' ExitError if proc is not a Process instance. Sends a 'noproc' 'EXIT' signal to calling process if the proc process is no longer alive.

When a process terminates, it sends an 'EXIT' signal is to all of its linked processes. If a process terminates normally, it sends a 'normal' 'EXIT' signal to its linked processes.

All links are bidirectional. That is, if process A calls link(B), then if process B terminates, it sends an 'EXIT' signal to process A. Conversely, if process A terminates, it likewise sends an 'EXIT' signal to process B.

Refer to the processFlag() function for details about handling signals.

spawnLink( func[, args...][, _processClass=Process])
This function is identical to the following code being evaluated in an atomic operation:
>>> proc = spawn(func, args...)
>>> link(proc)
This function is necessary since the process created might run immediately and fail before link() is called. Returns the Process instance of the newly created process. Raises a 'badarg' ExitError if func is not callable().

If you define a subclass of Process, you can instruct the spawnLink() function to create an instance of that class by passing the class with the optional _processClass keyword argument.

unlink( proc)
Remove the link, if there is one, from the calling process to another process given by the proc argument. The function does not fail if the calling process is not linked to proc, or if proc is not alive. Raises a 'badarg' ExitError if proc is not a Process instance.

isProcessAlive( proc)
Return True if the process is alive, i.e., has not terminated. Otherwise, return False. Raises a 'badarg' ExitError if proc is not a Process instance.

self( )
Return the Process instance of the calling process.

self_( )
An alias for the self() function. You can use this function in class methods where self is already defined.

processes( )
Return a list of all active processes.

send( proc, message)
Send the message to the proc process and return message. This is the same as proc.send(message). Raises a 'badarg' ExitError if proc is not a Process instance.

exit( [proc, ]reason)
When the proc argument is not given, this function raises an ExitError with the reason reason. reason can be any value.

When the proc argument is given, this function sends an 'EXIT' signal to the process proc. This is not necessarily the same as sending an 'EXIT' message to proc. They are the same if proc is trapping exits. If proc is not trapping exits, however, the proc process terminates and propagates the 'EXIT' signal in turn to its linked processes.

If the reason is the string 'kill', an untrappable 'EXIT' signal is sent to the process. In other words, the proc process is unconditionally killed.

Refer to the processFlag() function for details about trapping exits.

processFlag( flag, option)
Set the given flag for the calling process. Returns the old value of the flag. Raises a 'badarg' ExitError if flag is not a recognized flag value, or if option is not a recognized value for flag.

Currently, 'trap_exit' is the only recognized flag value. When 'trap_exit' is set to True, 'EXIT' signals arriving to a process are converted to ('EXIT', from, reason) messages, which can be received as ordinary messages. If 'trap_exit' is set to False, the process exits if it receives an 'EXIT' signal other than 'normal' and propagates the 'EXIT' signal to its linked processes. Application processes should normally not trap exits.

4.2 Process Objects

class Process( )
Represents a concurrent process. A Process is never created via its constructor. The spawn() and spawnLink() functions create all processes.

isProcessAlive( )
Return True if the process is alive, i.e., has not terminated. Otherwise, return False.

isAlive( )
An alias for the isProcessAlive() method. (The word ``process'' is redundant in a method name when the method is a member of the Process class.)

send( message)
Send the message to this process and return message. A routine running in a separate process calls this method to place the given message into this process's mailbox. A Receiver that is operating in this process may then pick up the message.

Sending a message is an asynchronous operation so the send() call does not wait for a Receiver to retrieve the message. Even if this process has already terminated, the system does not notify the sender. Messages are always delivered, and always in the same order they were sent.

__or__( message)
  An alias for the send() method. The OR operator, `|', is an alias to the send() method so that developers can use a more Erlangy syntax to send messages. In Erlang, the `!' primitive sends messages. For example:
>>> proc | ('knock-knock', 'candygram')

 
4.3 Receiver Objects

class Receiver( )
Retrieves messages from a process's mailbox. Every process maintains a mailbox, which contains messages that have been sent to it via the send() method. To retrieve the messages out of the mailbox, a process must use a Receiver object. Like the receive statement in Erlang, a Receiver object compares an incoming message against multiple patterns and invokes the callback function that is associated with the first matching pattern. Refer to section 3 for details about how to specify message patterns.

addHandler( pattern[, func[, args...]])
Register a handler function func for the pattern. The receive() method calls the func with the args argument list when it receives a message that matches pattern. When a handler function func is not specified, the receive() method removes any matching message from the mailbox and does nothing more with it. Refer to section 3 for details about how to specify message patterns. Returns a handler reference that can be used with the removeHandler() method. Raises a 'badarg' ExitError if func is not callable().

If any of the args arguments is candygram.Message, then the receive() method replaces that argument with the matching message when it invokes func.

Refer to the receive() documentation for details about the mechanism by which it invokes the handlers.

__setitem__( pattern, funcWithArgs)
  An alias for the addHandler() method. If funcWithArgs is a tuple, then this method sends the first element in the tuple as the func parameter to addHandler() and the remaining as the args. If funcWithArgs is not a tuple, then this method assumes it to be a handler function and sends it as the func parameter to addHandler().

__setitem__() is an alias to the addHandler() method so that developers can use a more Erlangy syntax to specify handlers. In Erlang, the ``pattern -> func'' syntax specifies pattern guards. For example:

>>> r = Receiver()
>>> r['knock-knock', 'candygram'] = answer, 'From whom?'

__getitem__( pattern)
  An alias for the addHandler() method. This method calls addHandler() without a func parameter.

__getitem__() is an alias to the addHandler() method so that developers can use a more Erlangy syntax to specify handlers. In Erlang, the ``pattern -> func'' syntax specifies pattern guards. For example:

>>> r = Receiver()
>>> r['knock-knock', 'shark']  # ignore sharks

addHandlers( receiver)
Register all handler functions in receiver with this Receiver object. This method adds all of the patterns and handler functions that have been added to the given receiver to this receiver, in the same order. You can use this method to make copies of Receiver objects. Returns a list of handler references that can be used with the removeHandler() method. Raises a 'badarg' ExitError if receiver is not a Receiver instance.

removeHandler( handlerReference)
Remove a handler function. The handlerReference must be a value returned by either the addHandler() or the addHandlers() method. Since all handler references are unique, this method removes exactly one handler function from the Receiver. Raises a 'badarg' ExitError if handlerReference is not a proper reference, or if it refers to a handler function that is not in the Receiver.

after( timeout[, func[, args...]])
Register a timeout handler function func. The receive() method calls the func with the args argument list when it does not receive a matching message within timeout milliseconds. Raises a 'badarg' ExitError if func is not callable() or if timeout is not an integer. Raises an AssertionError if the after() method has already been invoked.

If the receive() method does not find a matching message within timeout milliseconds, it invokes func with args and returns the result. When a handler function func is not specified, the receive() method returns None if it times out.

None of the args arguments should be candygram.Message, since there is no message to pass when a timeout occurs.

receive( [timeout[, func[, args...]]])
Find a matching message in the process's mailbox, invoke the related handler function, and return the result. The Receiver object compares the first message in the process's mailbox with each of its registered patterns, in the order that the patterns were added via the addHandler() method. If any pattern matches the message, this method removes the message from the mailbox, calls the associated handler function, and returns its result. If the matching pattern does not have a handler function associated with it, this method returns None. If no pattern matches the message, this method leaves the message in the mailbox, skips to the next message in the mailbox, and compares it with each of the patterns. It continues on through each of the messages in the mailbox until a match is found.

If no message matches any of the patterns, or if the mailbox is empty, this method blocks until the process receives a message that does match one of the patterns, or until the given timeout has elapsed. If no timeout is specified, this method blocks indefinitely. If a timeout is specified, it is equivalent to calling after(timeout, func, args) just prior to receive(). Raises a 'badarg' ExitError if func is not callable() or if timeout is not an integer. Also raises an AssertionError if a timeout is specified and the after() method has already been invoked.

__call__( [timeout[, func[, args...]]])
  An alias for the receive() method. __call__() is an alias to the receive() method so that developers can use a shortened, more Erlangy syntax with Receivers. For example:
>>> def convert():
...     r = Receiver()
...     r['one'] = lambda: 1
...     r['two'] = lambda: 2
...     r['three'] = lambda: 3
...     return r()

__iter__( )
Return an iterator that repeatedly invokes receive(). Candygram code often uses the following idiom:
... while True:
...     result = receiver.receive()
...     # do whatever with the result...
With an iterator, you can spell the code above like this instead:
... for result in receiver:
...     # do whatever with the result...

4.4 Constants

Any
When used in a pattern, the Any constant will match any value.

Message
When used as a function argument in Receiver.addHandler(), the Receiver.receive() method replaces the argument with the matching message when it invokes the handler function.

4.5 Exceptions

exception ExitError
Represents 'EXIT' errors from Erlang. If an Erlang function can cause a failure under certain circumstances, then the corresponding Candygram function raises an ExitError under the same circumstances.

A process also raises an ExitError in all of its linked processes if it terminates for a reason other than 'normal'.

Note: When a process terminates with a reason other than 'normal', it does not immediately raise an ExitError in all linked processes. Candygram defers the ExitError instead, and raises it the next time one of its functions or methods is called. (Python does not allow you to unconditionally interrupt a separate thread.)

reason
Specifies the reason why the ExitError was raised. Can be any value.

proc
The process that originally caused the ExitError.

SourceForge.net Logo