| | |
- zymb.sched.Agent
-
- TCP
-
- TCPSecure
-
- SSL
- TCPListen
class SSL(TCPSecure) |
| |
SSL: A subclass of the TCPSecure Agent which is intended to communicate
with an SSL server. It begins secure communication as soon as the
connection is made.
(Note that SSL agents use the 'connected' state to indicate that the
socket is secure. This is different from the TCPSecure class, which
uses 'connected' to indicate an open connection, and then 'secure'
to indicate a successful beginssl() call. The general principle
is that, if you create any kind of TCP agent, the 'connected' state
is your signal to begin sending messages.)
TCP(host, port, sock=None) -- constructor.
If you do not supply a *sock* argument, this will open a socket
connection to the given *host* and *port*. If you do supply a *sock*,
the agent will make use of the existing socket (which must be open).
In either case, the TCP agent will "own" the socket, and will close it
when the agent shuts down.
(If you supply a *sock*, the *host* and *port* values are kept only
for logging messages. You can fill in filler values if you have nothing
meaningful to supply.)
Agent states and events:
state 'start': Open the socket (if appropriate) and begin watching it.
state 'open': The socket is open but not yet secure. The agent
immediately begins SSL negotiation and moves to 'connected'.
state 'connected': The socket is open and ready, in encrypted mode.
event 'handle' (str): Data has been received from the socket. (As with
all low-level Internet messaging, the data is not necessarily
terminated with a newline, and the sender's messages may be
divided up or merged together in transit. The bytes will, however,
arrive in the correct order.)
event 'error' (exc, agent): A low-level error has been detected.
Errors detected when the socket is being opened will stop the
agent; read/write errors will not.
event 'closed': The socket was closed from the other end. This will
be immediately followed by a jump to the 'end' state.
state 'end': Close the socket.
Publicly readable fields:
host -- the hostname the socket connects to
port -- the port number the socket connects to
sock -- the socket object itself (if open)
Public methods:
send(str) -- send data out through the socket.
basichandle(str) -- a simple event handler for 'handle'.
Internal methods:
connect() -- 'start' state handler.
gotactivity() -- handler for socket activity.
disconnect() -- 'end' state handler. |
| |
- Method resolution order:
- SSL
- TCPSecure
- TCP
- zymb.sched.Agent
Methods defined here:
- __init__(self, host, port, sock=None)
Data and other attributes defined here:
- connectimmediately = False
- logprefix = 'zymb.tcpssl'
Methods inherited from TCPSecure:
- beginssl(self)
- beginssl() -> None
Begin secure communication. You should only call this once in the
lifetime of the socket.
If SSL/TLS negotiation succeeds, the agent will jump to 'secure'
state. On error, jump to 'end'.
- disconnect(self)
- disconnect() -- internal 'end' state handler. Do not call.
Close the socket.
- gotactivity(self)
- gotactivity() -- internal handler for socket activity. Do not call.
Pull as much data from the socket as is currently available.
Perform a 'handle' event. If the socket has closed, jump to
state 'end'.
This falls back to TCP.gotactivity when in non-secure mode.
- send(self, dat)
- send(dat) -> int
Send data out through the socket. Return the number of bytes written.
The data is sent raw. If you want to send Unicode data, you must
encode it to a str -- via utf-8 or whatever -- before calling send().
This falls back to TCP.gotactivity when in non-secure mode.
Methods inherited from TCP:
- __str__(self)
- basichandle(self, dat)
- basichandle(dat) -> None
A simple event handler for 'handle'. This simply writes the
received data to stdout:
sys.stdout.write(dat)
This handler is not installed by default. You can enable it by
calling:
tcp.addhandler('handle', tcp.basichandle)
- connect(self)
- connect() -- internal 'start' state handler. Do not call.
Connect to the socket (if none was provided). If successful, jump
to state 'connected'. On error, jump to state 'end'.
Methods inherited from zymb.sched.Agent:
- addcleanupaction(self, ac)
- addcleanupaction(action) -> None
Add *action* to the list of actions to be removed when the agent
stops (i.e., jumps to the 'end' state).
This is intended for actions that an agent adds as handlers to
other agents. For example:
ac = otheragent.addhandler('event', self.foreigneventhandler)
# Ensure that ac is removed when *self* shuts down.
addcleanupaction(ac)
You do not need to list pollers or socket-checkers as cleanup
actions. Nor do you need to list handlers that an agent adds
to itself. (All these are automatically removed when the agent
shuts down.) You also don't have to worry about the case of
*otheragent* shutting down; when that happens, all handlers added
to it are removed.
- addhandler(self, state, op, *args)
- addhandler(eventname, op, *args) -> action
Add a state or event handler. The *eventname* is a string naming
the state or event you want to handle. The *op* and *args* are
the operation to perform when that state or event occurs.
(See queueaction() for the use of *op* and *args*.)
Handlers are invoked in last-added-first-run order. If an agent
has a built-in handler, it is added first, so it runs last. Handlers
that you add on later run earlier.
Returns the Action. (You can cancel the handler by calling
ac.remove().)
- addtimer(self, op, *args, **dic)
- addtimer(op, *args, delay=num, when=num, periodic=bool) -> action
Add a timed event. You must supply exactly one of the keyword
arguments *delay* and *when*. A *when* is an absolute time,
expressed as a number of seconds since the epoch (e.g., the kind
of value returned by time.time()). A *delay* is a relative time,
expressed as a number of seconds in the future.
It is legal to give a time in the past (or a negative *delay*).
In that case, this is similar to queueaction() -- the operation
will occur very soon. (Although it's still a "low priority"
action.)
If you supply *periodic*=True, the event will occur repeatedly,
every *delay* seconds. (The interval is inferred if you give
*when*.) In this case, you may NOT give a negative *delay* or
a time in the past -- it is meaningless for a periodic event to
have a period less than or equal to zero.
You can also create a periodic timer by calling addtimer with
a PeriodicAction, which is a subclass of Action. This is slightly
more flexible; the interval between calls is specified when
you create the PeriodicAction, but the delay before the first
call may be specified with *delay* or *when*.
See queueaction() for the use of *op* and *args*.
Returns the Action. (You can cancel the timer by calling
ac.remove().)
- basicerror(self, exc, agent)
- basicerror(exc, agent) -> None
A simple event handler for 'error'. This simply writes the
received data to stdout:
sys.stdout.write('Error: ' + str(agent) + ': ' + str(exc) + '
')
This handler is not installed by default. You can enable it by
calling:
ag.addhandler('error', ag.basicerror)
- jump(self, st, *exargs)
- jump(state, *args) -> None
Jump to a different operating state. (If the agent is already
in the given state, nothing happens.)
This queues up all the state transition handlers registered
for the new state. If you provide *args*, they are passed to the
handlers when they are called.
- perform(self, name, *exargs)
- perform(eventname, *args) -> None
Trigger an event.
This queues up all the event handlers registered for the given
event. If you provide *args*, they are passed to the handlers when
they are called.
- queueaction(self, op, *args)
- queueaction(op, *args) -> action
Invoke an action. The action will be handed to the scheduler, which
will run it very soon.
("Very soon" means "before the next timed event or network message
is handled." However, if you queue several actions, they will be
handled in the order you queued them.)
You can pass any callable as *op*; the (optional) *args* will be
passed to it as arguments. You can also, if you like, create
an Action object and pass it as *op*. You can still pass *args*
in this case; they'll be appended to the arguments bound into
the Action.
Returns the Action.
- registerpoll(self, op, *args, **dic)
- registerpoll(op, *args, interval=num) -> action
Add a repeating activity check. *interval* is a (mandatory) keyword
argument; the scheduler will invoke your operation at least every
*interval* seconds. (And at least once per sched.process() call.)
See queueaction() for the use of *op* and *args*. Your operation
should not do any work except for absorbing input and queueing
actions. Typically, it will collect the input and then call
perform(), triggering an event, so that the agent's event
handlers can do something with the input.
Returns the Action. (You can cancel it by calling ac.remove().)
- registersocket(self, fileno, op, *args)
- registersocket(socket, op, *args) -> action
Add a socket-based activity check. The *socket* may be a socket
object, or a number representing a fileno, or any object which
provides a fileno() method.
See queueaction() for the use of *op* and *args*. Your operation
should not do any work except for absorbing input and queueing
actions. Typically, it will collect the input and then call
perform(), triggering an event, so that the agent's event
handlers can do something with the input.
Returns the Action. (You can cancel it by calling ac.remove().)
- shutdown(self)
- shutdown() -- internal 'end' state handler. Do not call.
This is the final 'end' handler. It removes the agent from the
scheduler, and cancels all its remaining actions, timed events,
etc.
- start(self)
- start() -> None
Begin activity. The agent adds itself to the scheduler and moves
to the 'start' state. It does not actually begin doing work in
this call; that happens the next time the scheduler is invoked
(sched.process).
You should only call this once per agent.
- stop(self)
- stop() -> None
Stop activity. The agent moves to the 'end' state. Its 'end'
state handlers will take care of shutting it down and removing
it from the scheduler.
It is safe to call this on an agent which is already in 'end',
or which is completely shut down. (Nothing further will happen.)
(Remember, state handlers are not called as part of the stop()
method. They are run by the scheduler "soon" after stop() is
called. If you want to be sure the agent is completely stopped,
you can check the agent.live field. However, it is better to
register your own 'end' state handler, and consider the agent
stopped when that it called.)
Data and other attributes inherited from zymb.sched.Agent:
- agentcounter = 1
- hidden = False
|
class TCP(zymb.sched.Agent) |
| |
TCP: An Agent which attends to a single TCP-IP socket connection.
As is common for agents, TCP does not actually do any network work
until you start it and begin calling sched.process(). Also, it does
not (by default) do anything with received data. Incoming data
triggers a 'handle' event, but there is no preregistered handler for
this event. You can write your own, or install the basichandle()
handler. See below.
TCP(host, port, sock=None) -- constructor.
If you do not supply a *sock* argument, this will open a socket
connection to the given *host* and *port*. If you do supply a *sock*,
the agent will make use of the existing socket (which must be open).
In either case, the TCP agent will "own" the socket, and will close it
when the agent shuts down.
(If you supply a *sock*, the *host* and *port* values are kept only
for logging messages. You can fill in filler values if you have nothing
meaningful to supply.)
Agent states and events:
state 'start': Open the socket (if appropriate) and begin watching it.
state 'connected': The socket is open and ready.
event 'handle' (str): Data has been received from the socket. (As with
all low-level Internet messaging, the data is not necessarily
terminated with a newline, and the sender's messages may be
divided up or merged together in transit. The bytes will, however,
arrive in the correct order.)
event 'error' (exc, agent): A low-level error has been detected.
Errors detected when the socket is being opened will stop the
agent; read/write errors will not.
event 'closed': The socket was closed from the other end. This will
be immediately followed by a jump to the 'end' state.
state 'end': Close the socket.
Publicly readable fields:
host -- the hostname the socket connects to
port -- the port number the socket connects to
sock -- the socket object itself (if open)
Public methods:
send(str) -- send data out through the socket.
basichandle(str) -- a simple event handler for 'handle'.
Internal methods:
connect() -- 'start' state handler.
gotactivity() -- handler for socket activity.
disconnect() -- 'end' state handler. |
| |
Methods defined here:
- __init__(self, host, port, sock=None)
- __str__(self)
- basichandle(self, dat)
- basichandle(dat) -> None
A simple event handler for 'handle'. This simply writes the
received data to stdout:
sys.stdout.write(dat)
This handler is not installed by default. You can enable it by
calling:
tcp.addhandler('handle', tcp.basichandle)
- connect(self)
- connect() -- internal 'start' state handler. Do not call.
Connect to the socket (if none was provided). If successful, jump
to state 'connected'. On error, jump to state 'end'.
- disconnect(self)
- disconnect() -- internal 'end' state handler. Do not call.
Close the socket.
- gotactivity(self)
- gotactivity() -- internal handler for socket activity. Do not call.
Pull as much data from the socket as is currently available.
Perform a 'handle' event. If the socket has closed, perform 'closed'
and then jump to state 'end'.
- send(self, dat)
- send(dat) -> int
Send data out through the socket. Return the number of bytes written.
The data is sent raw. If you want to send Unicode data, you must
encode it to a str -- via utf-8 or whatever -- before calling send().
Data and other attributes defined here:
- connectimmediately = True
- logprefix = 'zymb.tcp'
Methods inherited from zymb.sched.Agent:
- addcleanupaction(self, ac)
- addcleanupaction(action) -> None
Add *action* to the list of actions to be removed when the agent
stops (i.e., jumps to the 'end' state).
This is intended for actions that an agent adds as handlers to
other agents. For example:
ac = otheragent.addhandler('event', self.foreigneventhandler)
# Ensure that ac is removed when *self* shuts down.
addcleanupaction(ac)
You do not need to list pollers or socket-checkers as cleanup
actions. Nor do you need to list handlers that an agent adds
to itself. (All these are automatically removed when the agent
shuts down.) You also don't have to worry about the case of
*otheragent* shutting down; when that happens, all handlers added
to it are removed.
- addhandler(self, state, op, *args)
- addhandler(eventname, op, *args) -> action
Add a state or event handler. The *eventname* is a string naming
the state or event you want to handle. The *op* and *args* are
the operation to perform when that state or event occurs.
(See queueaction() for the use of *op* and *args*.)
Handlers are invoked in last-added-first-run order. If an agent
has a built-in handler, it is added first, so it runs last. Handlers
that you add on later run earlier.
Returns the Action. (You can cancel the handler by calling
ac.remove().)
- addtimer(self, op, *args, **dic)
- addtimer(op, *args, delay=num, when=num, periodic=bool) -> action
Add a timed event. You must supply exactly one of the keyword
arguments *delay* and *when*. A *when* is an absolute time,
expressed as a number of seconds since the epoch (e.g., the kind
of value returned by time.time()). A *delay* is a relative time,
expressed as a number of seconds in the future.
It is legal to give a time in the past (or a negative *delay*).
In that case, this is similar to queueaction() -- the operation
will occur very soon. (Although it's still a "low priority"
action.)
If you supply *periodic*=True, the event will occur repeatedly,
every *delay* seconds. (The interval is inferred if you give
*when*.) In this case, you may NOT give a negative *delay* or
a time in the past -- it is meaningless for a periodic event to
have a period less than or equal to zero.
You can also create a periodic timer by calling addtimer with
a PeriodicAction, which is a subclass of Action. This is slightly
more flexible; the interval between calls is specified when
you create the PeriodicAction, but the delay before the first
call may be specified with *delay* or *when*.
See queueaction() for the use of *op* and *args*.
Returns the Action. (You can cancel the timer by calling
ac.remove().)
- basicerror(self, exc, agent)
- basicerror(exc, agent) -> None
A simple event handler for 'error'. This simply writes the
received data to stdout:
sys.stdout.write('Error: ' + str(agent) + ': ' + str(exc) + '
')
This handler is not installed by default. You can enable it by
calling:
ag.addhandler('error', ag.basicerror)
- jump(self, st, *exargs)
- jump(state, *args) -> None
Jump to a different operating state. (If the agent is already
in the given state, nothing happens.)
This queues up all the state transition handlers registered
for the new state. If you provide *args*, they are passed to the
handlers when they are called.
- perform(self, name, *exargs)
- perform(eventname, *args) -> None
Trigger an event.
This queues up all the event handlers registered for the given
event. If you provide *args*, they are passed to the handlers when
they are called.
- queueaction(self, op, *args)
- queueaction(op, *args) -> action
Invoke an action. The action will be handed to the scheduler, which
will run it very soon.
("Very soon" means "before the next timed event or network message
is handled." However, if you queue several actions, they will be
handled in the order you queued them.)
You can pass any callable as *op*; the (optional) *args* will be
passed to it as arguments. You can also, if you like, create
an Action object and pass it as *op*. You can still pass *args*
in this case; they'll be appended to the arguments bound into
the Action.
Returns the Action.
- registerpoll(self, op, *args, **dic)
- registerpoll(op, *args, interval=num) -> action
Add a repeating activity check. *interval* is a (mandatory) keyword
argument; the scheduler will invoke your operation at least every
*interval* seconds. (And at least once per sched.process() call.)
See queueaction() for the use of *op* and *args*. Your operation
should not do any work except for absorbing input and queueing
actions. Typically, it will collect the input and then call
perform(), triggering an event, so that the agent's event
handlers can do something with the input.
Returns the Action. (You can cancel it by calling ac.remove().)
- registersocket(self, fileno, op, *args)
- registersocket(socket, op, *args) -> action
Add a socket-based activity check. The *socket* may be a socket
object, or a number representing a fileno, or any object which
provides a fileno() method.
See queueaction() for the use of *op* and *args*. Your operation
should not do any work except for absorbing input and queueing
actions. Typically, it will collect the input and then call
perform(), triggering an event, so that the agent's event
handlers can do something with the input.
Returns the Action. (You can cancel it by calling ac.remove().)
- shutdown(self)
- shutdown() -- internal 'end' state handler. Do not call.
This is the final 'end' handler. It removes the agent from the
scheduler, and cancels all its remaining actions, timed events,
etc.
- start(self)
- start() -> None
Begin activity. The agent adds itself to the scheduler and moves
to the 'start' state. It does not actually begin doing work in
this call; that happens the next time the scheduler is invoked
(sched.process).
You should only call this once per agent.
- stop(self)
- stop() -> None
Stop activity. The agent moves to the 'end' state. Its 'end'
state handlers will take care of shutting it down and removing
it from the scheduler.
It is safe to call this on an agent which is already in 'end',
or which is completely shut down. (Nothing further will happen.)
(Remember, state handlers are not called as part of the stop()
method. They are run by the scheduler "soon" after stop() is
called. If you want to be sure the agent is completely stopped,
you can check the agent.live field. However, it is better to
register your own 'end' state handler, and consider the agent
stopped when that it called.)
Data and other attributes inherited from zymb.sched.Agent:
- agentcounter = 1
- hidden = False
|
class TCPListen(zymb.sched.Agent) |
| |
TCPListen: An Agent which listens for incoming TCP-IP connections.
As is common for agents, TCP does not actually do any network work
until you start it and begin calling sched.process(). Also, it does
not (by default) do anything with accepted sockets. When someone
makes a connection, it triggers an 'accept' event, but there is
no preregistered handler for this event. You can write your own, or
install the basicaccept() handler. See below. (If you do not install
a handler, the socket will linger forever, unused and never closed.)
TCPListen(port) -- constructor.
Agent states and events:
state 'start': Open the socket and begin listening.
state 'listening': The socket is open and listening.
event 'accept' (socket, hostname, port): An incoming connection has been
accepted from this *hostname* (str) and *port* (int).
state 'end': Close the listening socket.
Publicly readable fields:
port -- the port number the socket is listening on
sock -- the socket object itself (if open)
Public methods:
basicaccept(socket, host, port) -- a simple event handler for 'accept'.
Internal methods:
connect() -- 'start' state handler.
gotactivity() -- handler for socket activity.
disconnect() -- 'end' state handler. |
| |
Methods defined here:
- __init__(self, port)
- __str__(self)
- basicaccept(self, sock, host, port)
- basicaccept(socket, host, port) -> None
A simple event handler for 'accept'. This creates a TCP agent to
manage the socket, and starts it:
cl = TCP(host, port, socket)
cl.start()
This handler is not installed by default. You can enable it by
calling:
tcpl.addhandler('accept', tcpl.basicaccept)
- connect(self)
- connect() -- internal 'start' state handler. Do not call.
Bind the socket and start listening. If successful, jump
to state 'listening'. On error, jump to state 'end'.
- disconnect(self)
- disconnect() -- internal 'end' state handler. Do not call.
Close the socket.
- gotactivity(self)
- gotactivity() -- internal handler for socket activity. Do not call.
Accept the incoming socket connection. Perform an 'accept' event.
Data and other attributes defined here:
- logprefix = 'zymb.tcplisten'
Methods inherited from zymb.sched.Agent:
- addcleanupaction(self, ac)
- addcleanupaction(action) -> None
Add *action* to the list of actions to be removed when the agent
stops (i.e., jumps to the 'end' state).
This is intended for actions that an agent adds as handlers to
other agents. For example:
ac = otheragent.addhandler('event', self.foreigneventhandler)
# Ensure that ac is removed when *self* shuts down.
addcleanupaction(ac)
You do not need to list pollers or socket-checkers as cleanup
actions. Nor do you need to list handlers that an agent adds
to itself. (All these are automatically removed when the agent
shuts down.) You also don't have to worry about the case of
*otheragent* shutting down; when that happens, all handlers added
to it are removed.
- addhandler(self, state, op, *args)
- addhandler(eventname, op, *args) -> action
Add a state or event handler. The *eventname* is a string naming
the state or event you want to handle. The *op* and *args* are
the operation to perform when that state or event occurs.
(See queueaction() for the use of *op* and *args*.)
Handlers are invoked in last-added-first-run order. If an agent
has a built-in handler, it is added first, so it runs last. Handlers
that you add on later run earlier.
Returns the Action. (You can cancel the handler by calling
ac.remove().)
- addtimer(self, op, *args, **dic)
- addtimer(op, *args, delay=num, when=num, periodic=bool) -> action
Add a timed event. You must supply exactly one of the keyword
arguments *delay* and *when*. A *when* is an absolute time,
expressed as a number of seconds since the epoch (e.g., the kind
of value returned by time.time()). A *delay* is a relative time,
expressed as a number of seconds in the future.
It is legal to give a time in the past (or a negative *delay*).
In that case, this is similar to queueaction() -- the operation
will occur very soon. (Although it's still a "low priority"
action.)
If you supply *periodic*=True, the event will occur repeatedly,
every *delay* seconds. (The interval is inferred if you give
*when*.) In this case, you may NOT give a negative *delay* or
a time in the past -- it is meaningless for a periodic event to
have a period less than or equal to zero.
You can also create a periodic timer by calling addtimer with
a PeriodicAction, which is a subclass of Action. This is slightly
more flexible; the interval between calls is specified when
you create the PeriodicAction, but the delay before the first
call may be specified with *delay* or *when*.
See queueaction() for the use of *op* and *args*.
Returns the Action. (You can cancel the timer by calling
ac.remove().)
- basicerror(self, exc, agent)
- basicerror(exc, agent) -> None
A simple event handler for 'error'. This simply writes the
received data to stdout:
sys.stdout.write('Error: ' + str(agent) + ': ' + str(exc) + '
')
This handler is not installed by default. You can enable it by
calling:
ag.addhandler('error', ag.basicerror)
- jump(self, st, *exargs)
- jump(state, *args) -> None
Jump to a different operating state. (If the agent is already
in the given state, nothing happens.)
This queues up all the state transition handlers registered
for the new state. If you provide *args*, they are passed to the
handlers when they are called.
- perform(self, name, *exargs)
- perform(eventname, *args) -> None
Trigger an event.
This queues up all the event handlers registered for the given
event. If you provide *args*, they are passed to the handlers when
they are called.
- queueaction(self, op, *args)
- queueaction(op, *args) -> action
Invoke an action. The action will be handed to the scheduler, which
will run it very soon.
("Very soon" means "before the next timed event or network message
is handled." However, if you queue several actions, they will be
handled in the order you queued them.)
You can pass any callable as *op*; the (optional) *args* will be
passed to it as arguments. You can also, if you like, create
an Action object and pass it as *op*. You can still pass *args*
in this case; they'll be appended to the arguments bound into
the Action.
Returns the Action.
- registerpoll(self, op, *args, **dic)
- registerpoll(op, *args, interval=num) -> action
Add a repeating activity check. *interval* is a (mandatory) keyword
argument; the scheduler will invoke your operation at least every
*interval* seconds. (And at least once per sched.process() call.)
See queueaction() for the use of *op* and *args*. Your operation
should not do any work except for absorbing input and queueing
actions. Typically, it will collect the input and then call
perform(), triggering an event, so that the agent's event
handlers can do something with the input.
Returns the Action. (You can cancel it by calling ac.remove().)
- registersocket(self, fileno, op, *args)
- registersocket(socket, op, *args) -> action
Add a socket-based activity check. The *socket* may be a socket
object, or a number representing a fileno, or any object which
provides a fileno() method.
See queueaction() for the use of *op* and *args*. Your operation
should not do any work except for absorbing input and queueing
actions. Typically, it will collect the input and then call
perform(), triggering an event, so that the agent's event
handlers can do something with the input.
Returns the Action. (You can cancel it by calling ac.remove().)
- shutdown(self)
- shutdown() -- internal 'end' state handler. Do not call.
This is the final 'end' handler. It removes the agent from the
scheduler, and cancels all its remaining actions, timed events,
etc.
- start(self)
- start() -> None
Begin activity. The agent adds itself to the scheduler and moves
to the 'start' state. It does not actually begin doing work in
this call; that happens the next time the scheduler is invoked
(sched.process).
You should only call this once per agent.
- stop(self)
- stop() -> None
Stop activity. The agent moves to the 'end' state. Its 'end'
state handlers will take care of shutting it down and removing
it from the scheduler.
It is safe to call this on an agent which is already in 'end',
or which is completely shut down. (Nothing further will happen.)
(Remember, state handlers are not called as part of the stop()
method. They are run by the scheduler "soon" after stop() is
called. If you want to be sure the agent is completely stopped,
you can check the agent.live field. However, it is better to
register your own 'end' state handler, and consider the agent
stopped when that it called.)
Data and other attributes inherited from zymb.sched.Agent:
- agentcounter = 1
- hidden = False
|
class TCPSecure(TCP) |
| |
TCPSecure: A subclass of the TCP Agent which is capable of SSL/TLS
secure communication.
A TCPSecure agent behaves just like a plain TCP agent, communicating
in the clear, until its beginssl() method is called. If that succeeds,
subsequent communication will be encrypted. (If it fails, the socket
will be closed.)
TCPSecure(host, port, sock=None) -- constructor.
If you do not supply a *sock* argument, this will open a socket
connection to the given *host* and *port*. If you do supply a *sock*,
the agent will make use of the existing socket (which must be open).
In either case, the TCPSecure agent will "own" the socket, and will close
it when the agent shuts down.
(If you supply a *sock*, the *host* and *port* values are kept only
for logging messages. You can fill in filler values if you have nothing
meaningful to supply.)
Agent states and events:
state 'start': Open the socket (if appropriate) and begin watching it.
state 'connected': The socket is open and ready.
state 'secure': Encrypted communication has begun.
event 'handle' (str): Data has been received from the socket. (As with
all low-level Internet messaging, the data is not necessarily
terminated with a newline, and the sender's messages may be
divided up or merged together in transit. The bytes will, however,
arrive in the correct order.)
event 'error' (exc, agent): A low-level error has been detected.
Errors detected when the socket is being opened will stop the
agent; read/write errors will not.
event 'closed': The socket was closed from the other end. This will
be immediately followed by a jump to the 'end' state.
state 'end': Close the socket.
Publicly readable fields:
host -- the hostname the socket connects to
port -- the port number the socket connects to
sock -- the socket object itself (if open)
ssl -- the socket.ssl object (if in secure mode) or None (if not)
Public methods:
send(str) -- send data out through the socket.
basichandle(str) -- a simple event handler for 'handle'.
beginssl() -- begin secure communication.
Internal methods:
connect() -- 'start' state handler.
gotactivity() -- handler for socket activity.
disconnect() -- 'end' state handler. |
| |
- Method resolution order:
- TCPSecure
- TCP
- zymb.sched.Agent
Methods defined here:
- __init__(self, host, port, sock=None)
- beginssl(self)
- beginssl() -> None
Begin secure communication. You should only call this once in the
lifetime of the socket.
If SSL/TLS negotiation succeeds, the agent will jump to 'secure'
state. On error, jump to 'end'.
- disconnect(self)
- disconnect() -- internal 'end' state handler. Do not call.
Close the socket.
- gotactivity(self)
- gotactivity() -- internal handler for socket activity. Do not call.
Pull as much data from the socket as is currently available.
Perform a 'handle' event. If the socket has closed, jump to
state 'end'.
This falls back to TCP.gotactivity when in non-secure mode.
- send(self, dat)
- send(dat) -> int
Send data out through the socket. Return the number of bytes written.
The data is sent raw. If you want to send Unicode data, you must
encode it to a str -- via utf-8 or whatever -- before calling send().
This falls back to TCP.gotactivity when in non-secure mode.
Data and other attributes defined here:
- logprefix = 'zymb.tcpsecure'
Methods inherited from TCP:
- __str__(self)
- basichandle(self, dat)
- basichandle(dat) -> None
A simple event handler for 'handle'. This simply writes the
received data to stdout:
sys.stdout.write(dat)
This handler is not installed by default. You can enable it by
calling:
tcp.addhandler('handle', tcp.basichandle)
- connect(self)
- connect() -- internal 'start' state handler. Do not call.
Connect to the socket (if none was provided). If successful, jump
to state 'connected'. On error, jump to state 'end'.
Data and other attributes inherited from TCP:
- connectimmediately = True
Methods inherited from zymb.sched.Agent:
- addcleanupaction(self, ac)
- addcleanupaction(action) -> None
Add *action* to the list of actions to be removed when the agent
stops (i.e., jumps to the 'end' state).
This is intended for actions that an agent adds as handlers to
other agents. For example:
ac = otheragent.addhandler('event', self.foreigneventhandler)
# Ensure that ac is removed when *self* shuts down.
addcleanupaction(ac)
You do not need to list pollers or socket-checkers as cleanup
actions. Nor do you need to list handlers that an agent adds
to itself. (All these are automatically removed when the agent
shuts down.) You also don't have to worry about the case of
*otheragent* shutting down; when that happens, all handlers added
to it are removed.
- addhandler(self, state, op, *args)
- addhandler(eventname, op, *args) -> action
Add a state or event handler. The *eventname* is a string naming
the state or event you want to handle. The *op* and *args* are
the operation to perform when that state or event occurs.
(See queueaction() for the use of *op* and *args*.)
Handlers are invoked in last-added-first-run order. If an agent
has a built-in handler, it is added first, so it runs last. Handlers
that you add on later run earlier.
Returns the Action. (You can cancel the handler by calling
ac.remove().)
- addtimer(self, op, *args, **dic)
- addtimer(op, *args, delay=num, when=num, periodic=bool) -> action
Add a timed event. You must supply exactly one of the keyword
arguments *delay* and *when*. A *when* is an absolute time,
expressed as a number of seconds since the epoch (e.g., the kind
of value returned by time.time()). A *delay* is a relative time,
expressed as a number of seconds in the future.
It is legal to give a time in the past (or a negative *delay*).
In that case, this is similar to queueaction() -- the operation
will occur very soon. (Although it's still a "low priority"
action.)
If you supply *periodic*=True, the event will occur repeatedly,
every *delay* seconds. (The interval is inferred if you give
*when*.) In this case, you may NOT give a negative *delay* or
a time in the past -- it is meaningless for a periodic event to
have a period less than or equal to zero.
You can also create a periodic timer by calling addtimer with
a PeriodicAction, which is a subclass of Action. This is slightly
more flexible; the interval between calls is specified when
you create the PeriodicAction, but the delay before the first
call may be specified with *delay* or *when*.
See queueaction() for the use of *op* and *args*.
Returns the Action. (You can cancel the timer by calling
ac.remove().)
- basicerror(self, exc, agent)
- basicerror(exc, agent) -> None
A simple event handler for 'error'. This simply writes the
received data to stdout:
sys.stdout.write('Error: ' + str(agent) + ': ' + str(exc) + '
')
This handler is not installed by default. You can enable it by
calling:
ag.addhandler('error', ag.basicerror)
- jump(self, st, *exargs)
- jump(state, *args) -> None
Jump to a different operating state. (If the agent is already
in the given state, nothing happens.)
This queues up all the state transition handlers registered
for the new state. If you provide *args*, they are passed to the
handlers when they are called.
- perform(self, name, *exargs)
- perform(eventname, *args) -> None
Trigger an event.
This queues up all the event handlers registered for the given
event. If you provide *args*, they are passed to the handlers when
they are called.
- queueaction(self, op, *args)
- queueaction(op, *args) -> action
Invoke an action. The action will be handed to the scheduler, which
will run it very soon.
("Very soon" means "before the next timed event or network message
is handled." However, if you queue several actions, they will be
handled in the order you queued them.)
You can pass any callable as *op*; the (optional) *args* will be
passed to it as arguments. You can also, if you like, create
an Action object and pass it as *op*. You can still pass *args*
in this case; they'll be appended to the arguments bound into
the Action.
Returns the Action.
- registerpoll(self, op, *args, **dic)
- registerpoll(op, *args, interval=num) -> action
Add a repeating activity check. *interval* is a (mandatory) keyword
argument; the scheduler will invoke your operation at least every
*interval* seconds. (And at least once per sched.process() call.)
See queueaction() for the use of *op* and *args*. Your operation
should not do any work except for absorbing input and queueing
actions. Typically, it will collect the input and then call
perform(), triggering an event, so that the agent's event
handlers can do something with the input.
Returns the Action. (You can cancel it by calling ac.remove().)
- registersocket(self, fileno, op, *args)
- registersocket(socket, op, *args) -> action
Add a socket-based activity check. The *socket* may be a socket
object, or a number representing a fileno, or any object which
provides a fileno() method.
See queueaction() for the use of *op* and *args*. Your operation
should not do any work except for absorbing input and queueing
actions. Typically, it will collect the input and then call
perform(), triggering an event, so that the agent's event
handlers can do something with the input.
Returns the Action. (You can cancel it by calling ac.remove().)
- shutdown(self)
- shutdown() -- internal 'end' state handler. Do not call.
This is the final 'end' handler. It removes the agent from the
scheduler, and cancels all its remaining actions, timed events,
etc.
- start(self)
- start() -> None
Begin activity. The agent adds itself to the scheduler and moves
to the 'start' state. It does not actually begin doing work in
this call; that happens the next time the scheduler is invoked
(sched.process).
You should only call this once per agent.
- stop(self)
- stop() -> None
Stop activity. The agent moves to the 'end' state. Its 'end'
state handlers will take care of shutting it down and removing
it from the scheduler.
It is safe to call this on an agent which is already in 'end',
or which is completely shut down. (Nothing further will happen.)
(Remember, state handlers are not called as part of the stop()
method. They are run by the scheduler "soon" after stop() is
called. If you want to be sure the agent is completely stopped,
you can check the agent.live field. However, it is better to
register your own 'end' state handler, and consider the agent
stopped when that it called.)
Data and other attributes inherited from zymb.sched.Agent:
- agentcounter = 1
- hidden = False
| |