issue #76, #370: add fix for disconnect cleanup test

Simply listen to RouteMonitor's Context "disconnect"  and forget
contexts according to RouteMonitor's rules, rather than duplicate them
(and screw it up).
This commit is contained in:
David Wilson 2018-11-01 20:06:09 +00:00
parent c148c869e6
commit bac28bc5ca
1 changed files with 10 additions and 17 deletions

View File

@ -297,23 +297,19 @@ class ContextService(mitogen.service.Service):
finally: finally:
self._lock.release() self._lock.release()
def _on_stream_disconnect(self, stream): def _on_context_disconnect(self, context):
""" """
Respond to Stream disconnection by deleting any record of contexts Respond to Context disconnect event by deleting any record of the no
reached via that stream. This method runs in the Broker thread and must longer reachable context. This method runs in the Broker thread and
not to block. must not to block.
""" """
# TODO: there is a race between creation of a context and disconnection # TODO: there is a race between creation of a context and disconnection
# of its related stream. An error reply should be sent to any message # of its related stream. An error reply should be sent to any message
# in _latches_by_key below. # in _latches_by_key below.
self._lock.acquire() self._lock.acquire()
try: try:
routes = self.router.route_monitor.get_routes(stream) LOG.info('Forgetting %r due to stream disconnect', context)
for context in list(self._key_by_context): self._forget_context_unlocked(context)
if context.context_id in routes:
LOG.info('Dropping %r due to disconnect of %r',
context, stream)
self._forget_context_unlocked(context)
finally: finally:
self._lock.release() self._lock.release()
@ -379,13 +375,10 @@ class ContextService(mitogen.service.Service):
context = method(via=via, unidirectional=True, **spec['kwargs']) context = method(via=via, unidirectional=True, **spec['kwargs'])
if via and spec.get('enable_lru'): if via and spec.get('enable_lru'):
self._update_lru(context, spec, via) self._update_lru(context, spec, via)
else:
# For directly connected contexts, listen to the associated # Forget the context when its disconnect event fires.
# Stream's disconnect event and use it to invalidate dependent mitogen.core.listen(context, 'disconnect',
# Contexts. lambda: self._on_context_disconnect(context))
stream = self.router.stream_by_id(context.context_id)
mitogen.core.listen(stream, 'disconnect',
lambda: self._on_stream_disconnect(stream))
self._send_module_forwards(context) self._send_module_forwards(context)
init_child_result = context.call( init_child_result = context.call(