issue #155: parent: move master.Context into parent.
The Context and Router APIs for constructing children and making function calls should be available in every parent context, as user code wants to have access to the same API.
This commit is contained in:
parent
447353ecb8
commit
6a74edce6b
10
docs/api.rst
10
docs/api.rst
|
@ -732,12 +732,12 @@ Context Class
|
|||
No message was received and `deadline` passed.
|
||||
|
||||
|
||||
.. currentmodule:: mitogen.master
|
||||
.. currentmodule:: mitogen.parent
|
||||
|
||||
.. class:: Context
|
||||
|
||||
Extend :py:class:`mitogen.core.Router` with functionality useful to
|
||||
masters, and child contexts who later become masters. Currently when this
|
||||
masters, and child contexts who later become parents. Currently when this
|
||||
class is required, the target context's router is upgraded at runtime.
|
||||
|
||||
.. method:: call_async (fn, \*args, \*\*kwargs)
|
||||
|
@ -820,7 +820,7 @@ Receiver Class
|
|||
|
||||
Receivers are used to wait for pickled responses from another context to be
|
||||
sent to a handle registered in this context. A receiver may be single-use
|
||||
(as in the case of :py:meth:`mitogen.master.Context.call_async`) or
|
||||
(as in the case of :py:meth:`mitogen.parent.Context.call_async`) or
|
||||
multiple use.
|
||||
|
||||
:param mitogen.core.Router router:
|
||||
|
@ -1057,7 +1057,7 @@ A random assortment of utility functions useful on masters and children.
|
|||
functionality, such as annotating the safety of a Unicode string, or adding
|
||||
additional methods to a dict. However, cPickle loves to preserve those
|
||||
subtypes during serialization, resulting in CallError during :py:meth:`call
|
||||
<mitogen.master.Context.call>` in the target when it tries to deserialize
|
||||
<mitogen.parent.Context.call>` in the target when it tries to deserialize
|
||||
the data.
|
||||
|
||||
This function walks the object graph `obj`, producing a copy with any
|
||||
|
@ -1139,7 +1139,7 @@ Exceptions
|
|||
|
||||
.. class:: CallError (e)
|
||||
|
||||
Raised when :py:meth:`Context.call() <mitogen.master.Context.call>` fails.
|
||||
Raised when :py:meth:`Context.call() <mitogen.parent.Context.call>` fails.
|
||||
A copy of the traceback from the external context is appended to the
|
||||
exception message.
|
||||
|
||||
|
|
|
@ -206,8 +206,8 @@ After all initialization is complete, the child's main thread sits in a loop
|
|||
reading from a :py:class:`Channel <mitogen.core.Channel>` connected to the
|
||||
:py:data:`CALL_FUNCTION <mitogen.core.CALL_FUNCTION>` handle. This handle is
|
||||
written to by
|
||||
:py:meth:`call() <mitogen.master.Context.call>`
|
||||
and :py:meth:`call_async() <mitogen.master.Context.call_async>`.
|
||||
:py:meth:`call() <mitogen.parent.Context.call>`
|
||||
and :py:meth:`call_async() <mitogen.parent.Context.call_async>`.
|
||||
|
||||
:py:data:`CALL_FUNCTION <mitogen.core.CALL_FUNCTION>` only accepts requests
|
||||
from the context IDs listed in :py:data:`mitogen.parent_ids`, forming a chain
|
||||
|
@ -369,7 +369,7 @@ Children listen on the following handles:
|
|||
|
||||
Receives `(mod_name, class_name, func_name, args, kwargs)`
|
||||
5-tuples from
|
||||
:py:meth:`call_async() <mitogen.master.Context.call_async>`,
|
||||
:py:meth:`call_async() <mitogen.parent.Context.call_async>`,
|
||||
imports ``mod_name``, then attempts to execute
|
||||
`class_name.func_name(\*args, \**kwargs)`.
|
||||
|
||||
|
@ -430,7 +430,7 @@ also listen on the following handles:
|
|||
|
||||
|
||||
Additional handles are created to receive the result of every function call
|
||||
triggered by :py:meth:`call_async() <mitogen.master.Context.call_async>`.
|
||||
triggered by :py:meth:`call_async() <mitogen.parent.Context.call_async>`.
|
||||
|
||||
|
||||
Sentinel Value
|
||||
|
|
|
@ -287,7 +287,7 @@ def _fakessh_main(dest_context_id, econtext):
|
|||
if not args:
|
||||
die('fakessh: login mode not supported and no command specified')
|
||||
|
||||
dest = mitogen.master.Context(econtext.router, dest_context_id)
|
||||
dest = mitogen.parent.Context(econtext.router, dest_context_id)
|
||||
|
||||
# Even though SSH receives an argument vector, it still cats the vector
|
||||
# together before sending to the server, the server just uses /bin/sh -c to
|
||||
|
@ -318,7 +318,7 @@ def run(dest, router, args, deadline=None, econtext=None):
|
|||
mitogen.parent.upgrade_router(econtext)
|
||||
|
||||
context_id = router.allocate_id()
|
||||
fakessh = mitogen.master.Context(router, context_id)
|
||||
fakessh = mitogen.parent.Context(router, context_id)
|
||||
fakessh.name = 'fakessh.%d' % (context_id,)
|
||||
|
||||
sock1, sock2 = socket.socketpair()
|
||||
|
@ -345,8 +345,8 @@ def run(dest, router, args, deadline=None, econtext=None):
|
|||
fp.write('ExternalContext().main(**%r)\n' % ({
|
||||
'parent_ids': parent_ids,
|
||||
'context_id': context_id,
|
||||
'debug': router.debug,
|
||||
'profiling': router.profiling,
|
||||
'debug': getattr(router, 'debug', False),
|
||||
'profiling': getattr(router, 'profiling', False),
|
||||
'log_level': mitogen.parent.get_log_level(),
|
||||
'in_fd': sock2.fileno(),
|
||||
'out_fd': sock2.fileno(),
|
||||
|
|
|
@ -641,33 +641,7 @@ class Broker(mitogen.core.Broker):
|
|||
self._watcher.remove()
|
||||
|
||||
|
||||
class Context(mitogen.core.Context):
|
||||
via = None
|
||||
|
||||
def call_async(self, fn, *args, **kwargs):
|
||||
LOG.debug('%r.call_async(%r, *%r, **%r)',
|
||||
self, fn, args, kwargs)
|
||||
|
||||
if isinstance(fn, types.MethodType) and \
|
||||
isinstance(fn.im_self, (type, types.ClassType)):
|
||||
klass = fn.im_self.__name__
|
||||
else:
|
||||
klass = None
|
||||
|
||||
return self.send_async(
|
||||
mitogen.core.Message.pickled(
|
||||
(fn.__module__, klass, fn.__name__, args, kwargs),
|
||||
handle=mitogen.core.CALL_FUNCTION,
|
||||
)
|
||||
)
|
||||
|
||||
def call(self, fn, *args, **kwargs):
|
||||
receiver = self.call_async(fn, *args, **kwargs)
|
||||
return receiver.get().unpickle(throw_dead=False)
|
||||
|
||||
|
||||
class Router(mitogen.parent.Router):
|
||||
context_class = Context
|
||||
broker_class = Broker
|
||||
debug = False
|
||||
profiling = False
|
||||
|
|
|
@ -39,6 +39,7 @@ import termios
|
|||
import textwrap
|
||||
import threading
|
||||
import time
|
||||
import types
|
||||
import zlib
|
||||
|
||||
import mitogen.core
|
||||
|
@ -467,6 +468,31 @@ class ChildIdAllocator(object):
|
|||
return self.allocate()
|
||||
|
||||
|
||||
class Context(mitogen.core.Context):
|
||||
via = None
|
||||
|
||||
def call_async(self, fn, *args, **kwargs):
|
||||
LOG.debug('%r.call_async(%r, *%r, **%r)',
|
||||
self, fn, args, kwargs)
|
||||
|
||||
if isinstance(fn, types.MethodType) and \
|
||||
isinstance(fn.im_self, (type, types.ClassType)):
|
||||
klass = fn.im_self.__name__
|
||||
else:
|
||||
klass = None
|
||||
|
||||
return self.send_async(
|
||||
mitogen.core.Message.pickled(
|
||||
(fn.__module__, klass, fn.__name__, args, kwargs),
|
||||
handle=mitogen.core.CALL_FUNCTION,
|
||||
)
|
||||
)
|
||||
|
||||
def call(self, fn, *args, **kwargs):
|
||||
receiver = self.call_async(fn, *args, **kwargs)
|
||||
return receiver.get().unpickle(throw_dead=False)
|
||||
|
||||
|
||||
class RouteMonitor(object):
|
||||
def __init__(self, router, parent=None):
|
||||
self.router = router
|
||||
|
@ -556,7 +582,7 @@ class RouteMonitor(object):
|
|||
|
||||
|
||||
class Router(mitogen.core.Router):
|
||||
context_class = mitogen.core.Context
|
||||
context_class = Context
|
||||
|
||||
id_allocator = None
|
||||
responder = None
|
||||
|
|
|
@ -83,7 +83,7 @@ class Listener(mitogen.core.BasicStream):
|
|||
pid, = struct.unpack('>L', sock.recv(4))
|
||||
|
||||
context_id = self._router.id_allocator.allocate()
|
||||
context = mitogen.master.Context(self._router, context_id)
|
||||
context = mitogen.parent.Context(self._router, context_id)
|
||||
stream = mitogen.core.Stream(self._router, context_id)
|
||||
stream.accept(sock.fileno(), sock.fileno())
|
||||
stream.name = 'unix_client.%d' % (pid,)
|
||||
|
@ -111,7 +111,7 @@ def connect(path, broker=None):
|
|||
stream.accept(sock.fileno(), sock.fileno())
|
||||
stream.name = 'unix_listener.%d' % (pid,)
|
||||
|
||||
context = mitogen.master.Context(router, remote_id)
|
||||
context = mitogen.parent.Context(router, remote_id)
|
||||
router.register(context, stream)
|
||||
|
||||
mitogen.core.listen(router.broker, 'shutdown',
|
||||
|
|
|
@ -13,7 +13,7 @@ import mitogen.ssh
|
|||
import mitogen.sudo
|
||||
|
||||
router = mitogen.master.Router()
|
||||
context = mitogen.master.Context(router, 0)
|
||||
context = mitogen.parent.Context(router, 0)
|
||||
stream = mitogen.ssh.Stream(router, 0, hostname='foo')
|
||||
|
||||
print 'SSH command size: %s' % (len(' '.join(stream.get_boot_command())),)
|
||||
|
|
Loading…
Reference in New Issue