Commit 14783c75 authored by David Wilson's avatar David Wilson

issue #9: log warning when a cross-sibling CALL_FUNCTION occurs

First step to making it a fatal error.
parent 9de1fca3
......@@ -31,3 +31,8 @@ context_id = 0
#: This is ``None`` in a master, otherwise it is the master-generated ID unique
#: to the slave's parent context.
parent_id = None
#: This is an empty list in a master, otherwise it is a list of parent context
#: IDs ordered from most direct to least direct.
parent_ids = []
......@@ -49,6 +49,10 @@ class Error(Exception):
Exception.__init__(self, fmt)
class SecurityError(Error):
pass
class CallError(Error):
def __init__(self, e):
s = '%s.%s: %s' % (type(e).__module__, type(e).__name__, e)
......@@ -1156,7 +1160,7 @@ class ExternalContext(object):
self.importer = Importer(self.parent, core_src)
sys.meta_path.append(self.importer)
def _setup_package(self, context_id, parent_id):
def _setup_package(self, context_id, parent_ids):
global mitogen
mitogen = imp.new_module('mitogen')
mitogen.__package__ = 'mitogen'
......@@ -1164,7 +1168,8 @@ class ExternalContext(object):
mitogen.__loader__ = self.importer
mitogen.is_master = False
mitogen.context_id = context_id
mitogen.parent_id = parent_id
mitogen.parent_ids = parent_ids
mitogen.parent_id = parent_ids[0]
mitogen.core = sys.modules['__main__']
mitogen.core.__file__ = 'x/mitogen/core.py' # For inspect.getsource()
mitogen.core.__loader__ = self.importer
......@@ -1187,8 +1192,10 @@ class ExternalContext(object):
def _dispatch_calls(self):
for msg, data in self.channel:
LOG.debug('_dispatch_calls(%r)', data)
modname, klass, func, args, kwargs = data
if msg.src_id not in mitogen.parent_ids:
LOG.warning('CALL_FUNCTION from non-parent %r', msg.src_id)
modname, klass, func, args, kwargs = data
try:
obj = __import__(modname, {}, {}, [''])
if klass:
......@@ -1209,14 +1216,14 @@ class ExternalContext(object):
Message.pickled(e, dst_id=msg.src_id, handle=msg.reply_to)
)
def main(self, parent_id, context_id, debug, profiling, log_level,
def main(self, parent_ids, context_id, debug, profiling, log_level,
in_fd=100, out_fd=1, core_src_fd=101, setup_stdio=True):
self._setup_master(profiling, parent_id, context_id, in_fd, out_fd)
self._setup_master(profiling, parent_ids[0], context_id, in_fd, out_fd)
try:
try:
self._setup_logging(debug, log_level)
self._setup_importer(core_src_fd)
self._setup_package(context_id, parent_id)
self._setup_package(context_id, parent_ids)
if setup_stdio:
self._setup_stdio()
......
......@@ -369,6 +369,9 @@ 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')
......@@ -378,7 +381,7 @@ def run(dest, router, args, deadline=None, econtext=None):
fp.write(inspect.getsource(mitogen.core))
fp.write('\n')
fp.write('ExternalContext().main%r\n' % ((
mitogen.context_id, # parent_id
parent_ids, # parent_ids
context_id, # context_id
router.debug, # debug
router.profiling, # profiling
......
......@@ -625,9 +625,11 @@ class Stream(mitogen.core.Stream):
'exec("%s".decode("base64"))' % (encoded,)]
def get_preamble(self):
parent_ids = mitogen.parent_ids[:]
parent_ids.insert(0, mitogen.context_id)
source = inspect.getsource(mitogen.core)
source += '\nExternalContext().main%r\n' % ((
mitogen.context_id, # parent_id
parent_ids, # parent_ids
self.remote_id, # context_id
self.debug,
self.profiling,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment