core: have ExternalContext accept a config dict rather than kwargs.

The parameter lists had gotten out of control.
pull/255/head
David Wilson 6 years ago
parent eac4cc7afe
commit 00edf0d66d

@ -1596,11 +1596,14 @@ class Broker(object):
class ExternalContext(object):
detached = False
def __init__(self, config):
self.config = config
def _on_broker_shutdown(self):
self.channel.close()
def _on_broker_exit(self):
if not self.profiling:
if not self.config['profiling']:
os.kill(os.getpid(), signal.SIGTERM)
def _on_shutdown_msg(self, msg):
@ -1638,29 +1641,31 @@ class ExternalContext(object):
LOG.error('Stream had %d bytes after 2000ms', pending)
self.broker.defer(stream.on_disconnect, self.broker)
def _setup_master(self, max_message_size, profiling, unidirectional,
parent_id, context_id, in_fd, out_fd):
Router.max_message_size = max_message_size
self.profiling = profiling
if profiling:
def _setup_master(self):
Router.max_message_size = self.config['max_message_size']
if self.config['profiling']:
enable_profiling()
self.broker = Broker()
self.router = Router(self.broker)
self.router.undirectional = unidirectional
self.router.undirectional = self.config['unidirectional']
self.router.add_handler(
fn=self._on_shutdown_msg,
handle=SHUTDOWN,
policy=has_parent_authority,
)
self.master = Context(self.router, 0, 'master')
parent_id = self.config['parent_ids'][0]
if parent_id == 0:
self.parent = self.master
else:
self.parent = Context(self.router, parent_id, 'parent')
self.channel = Receiver(router=self.router,
handle=CALL_FUNCTION,
policy=has_parent_authority)
in_fd = self.config.get('in_fd', 100)
out_fd = self.config.get('out_fd', 1)
self.recv = Receiver(router=self.router,
handle=CALL_FUNCTION,
policy=has_parent_authority)
self.stream = Stream(self.router, parent_id)
self.stream.name = 'parent'
self.stream.accept(in_fd, out_fd)
@ -1678,20 +1683,22 @@ class ExternalContext(object):
except OSError:
pass # No first stage exists (e.g. fakessh)
def _setup_logging(self, debug, log_level):
def _setup_logging(self):
root = logging.getLogger()
root.setLevel(log_level)
root.setLevel(self.config['log_level'])
root.handlers = [LogHandler(self.master)]
if debug:
if self.config['debug']:
enable_debug_logging()
def _setup_importer(self, importer, core_src_fd, whitelist, blacklist):
def _setup_importer(self):
importer = self.config.get('importer')
if importer:
importer._install_handler(self.router)
importer._context = self.parent
else:
core_src_fd = self.config.get('core_src_fd', 101)
if core_src_fd:
fp = os.fdopen(101, 'r', 1)
fp = os.fdopen(core_src_fd, 'r', 1)
try:
core_size = int(fp.readline())
core_src = fp.read(core_size)
@ -1702,8 +1709,13 @@ class ExternalContext(object):
else:
core_src = None
importer = Importer(self.router, self.parent,
core_src, whitelist, blacklist)
importer = Importer(
self.router,
self.parent,
core_src,
self.config.get('whitelist', ()),
self.config.get('blacklist', ()),
)
self.importer = importer
self.router.importer = importer
@ -1723,12 +1735,12 @@ class ExternalContext(object):
sys.modules['mitogen.core'] = mitogen.core
del sys.modules['__main__']
def _setup_globals(self, version, context_id, parent_ids):
mitogen.__version__ = version
def _setup_globals(self):
mitogen.is_master = False
mitogen.context_id = context_id
mitogen.parent_ids = parent_ids
mitogen.parent_id = parent_ids[0]
mitogen.__version__ = self.config['version']
mitogen.context_id = self.config['context_id']
mitogen.parent_ids = self.config['parent_ids'][:]
mitogen.parent_id = mitogen.parent_ids[0]
def _setup_stdio(self):
# We must open this prior to closing stdout, otherwise it will recycle
@ -1774,7 +1786,7 @@ class ExternalContext(object):
return fn(*args, **kwargs)
def _dispatch_calls(self):
for msg in self.channel:
for msg in self.recv:
try:
msg.reply(self._dispatch_one(msg))
except Exception:
@ -1783,28 +1795,24 @@ class ExternalContext(object):
msg.reply(CallError(e))
self.dispatch_stopped = True
def main(self, parent_ids, context_id, debug, profiling, log_level,
unidirectional, max_message_size, version, in_fd=100, out_fd=1,
core_src_fd=101, setup_stdio=True, setup_package=True,
importer=None, whitelist=(), blacklist=()):
self._setup_master(max_message_size, profiling, unidirectional,
parent_ids[0], context_id, in_fd, out_fd)
def main(self):
self._setup_master()
try:
try:
self._setup_logging(debug, log_level)
self._setup_importer(importer, core_src_fd, whitelist, blacklist)
self._setup_logging()
self._setup_importer()
self._reap_first_stage()
if setup_package:
if self.config.get('setup_package', True):
self._setup_package()
self._setup_globals(version, context_id, parent_ids)
if setup_stdio:
self._setup_globals()
if self.config.get('setup_stdio', True):
self._setup_stdio()
self.router.register(self.parent, self.stream)
sys.executable = os.environ.pop('ARGV0', sys.executable)
_v and LOG.debug('Connected to %s; my ID is %r, PID is %r',
self.parent, context_id, os.getpid())
self.parent, mitogen.context_id, os.getpid())
_v and LOG.debug('Recovered sys.executable: %r', sys.executable)
_profile_hook('main', self._dispatch_calls)

@ -304,6 +304,25 @@ def _fakessh_main(dest_context_id, econtext):
process.control.put(('exit', None))
def _get_econtext_config(context, sock2):
parent_ids = mitogen.parent_ids[:]
parent_ids.insert(0, mitogen.context_id)
return {
'context_id': context.context_id,
'core_src_fd': None,
'debug': getattr(context.router, 'debug', False),
'in_fd': sock2.fileno(),
'log_level': mitogen.parent.get_log_level(),
'max_message_size': context.router.max_message_size,
'out_fd': sock2.fileno(),
'parent_ids': parent_ids,
'profiling': getattr(context.router, 'profiling', False),
'unidirectional': getattr(context.router, 'unidirectional', False),
'setup_stdio': False,
'version': mitogen.__version__,
}
#
# Public API.
#
@ -328,9 +347,6 @@ def run(dest, router, args, deadline=None, econtext=None):
# Held in socket buffer until process is booted.
fakessh.call_async(_fakessh_main, dest.context_id)
parent_ids = mitogen.parent_ids[:]
parent_ids.insert(0, mitogen.context_id)
tmp_path = tempfile.mkdtemp(prefix='mitogen_fakessh')
try:
ssh_path = os.path.join(tmp_path, 'ssh')
@ -339,20 +355,9 @@ def run(dest, router, args, deadline=None, econtext=None):
fp.write('#!%s\n' % (sys.executable,))
fp.write(inspect.getsource(mitogen.core))
fp.write('\n')
fp.write('ExternalContext().main(**%r)\n' % ({
'context_id': context_id,
'core_src_fd': None,
'debug': getattr(router, 'debug', False),
'in_fd': sock2.fileno(),
'log_level': mitogen.parent.get_log_level(),
'max_message_size': router.max_message_size,
'out_fd': sock2.fileno(),
'parent_ids': parent_ids,
'profiling': getattr(router, 'profiling', False),
'unidirectional': getattr(router, 'unidirectional', False),
'setup_stdio': False,
'version': mitogen.__version__,
},))
fp.write('ExternalContext(%r).main()\n' % (
_get_econtext_config(context, sock2),
))
finally:
fp.close()

@ -148,12 +148,12 @@ class Stream(mitogen.parent.Stream):
os.close(devnull)
childfp.close()
kwargs = self.get_main_kwargs()
kwargs['core_src_fd'] = None
kwargs['importer'] = self.importer
kwargs['setup_package'] = False
config = self.get_econtext_config()
config['core_src_fd'] = None
config['importer'] = self.importer
config['setup_package'] = False
try:
mitogen.core.ExternalContext().main(**kwargs)
mitogen.core.ExternalContext(config).main()
finally:
# Don't trigger atexit handlers, they were copied from the parent.
os._exit(0)

@ -896,7 +896,7 @@ class Stream(mitogen.core.Stream):
'exec(_(_("%s".encode(),"base64"),"zip"))' % (encoded,)
]
def get_main_kwargs(self):
def get_econtext_config(self):
assert self.max_message_size is not None
parent_ids = mitogen.parent_ids[:]
parent_ids.insert(0, mitogen.context_id)
@ -915,8 +915,8 @@ class Stream(mitogen.core.Stream):
def get_preamble(self):
source = inspect.getsource(mitogen.core)
source += '\nExternalContext().main(**%r)\n' % (
self.get_main_kwargs(),
source += '\nExternalContext(%r).main()\n' % (
self.get_econtext_config(),
)
return zlib.compress(minimize_source(source), 9)

@ -1,6 +1,7 @@
import errno
import os
import subprocess
import sys
import tempfile
import time

Loading…
Cancel
Save