issue #369: refactor Connection to support reset()

Now the tests pass.
This commit is contained in:
David Wilson 2018-10-29 19:34:50 +00:00
parent 9b7c958e2e
commit 33412927f5
1 changed files with 50 additions and 21 deletions

View File

@ -550,7 +550,7 @@ class Connection(ansible.plugins.connection.ConnectionBase):
self.host_vars = task_vars['hostvars'] self.host_vars = task_vars['hostvars']
self.delegate_to_hostname = delegate_to_hostname self.delegate_to_hostname = delegate_to_hostname
self.loader_basedir = loader_basedir self.loader_basedir = loader_basedir
self.close(new_task=True) self._reset(mode='put')
def get_task_var(self, key, default=None): def get_task_var(self, key, default=None):
if self._task_vars and key in self._task_vars: if self._task_vars and key in self._task_vars:
@ -709,6 +709,20 @@ class Connection(ansible.plugins.connection.ConnectionBase):
self.get_chain().call_no_reply(os.mkdir, self._shell.tmpdir) self.get_chain().call_no_reply(os.mkdir, self._shell.tmpdir)
return self._shell.tmpdir return self._shell.tmpdir
def _reset_tmp_path(self):
"""
Called by _reset(); ask the remote context to delete any temporary
directory created for the action. CallChain is not used here to ensure
exception is logged by the context on failure, since the CallChain
itself is about to be destructed.
"""
if getattr(self._shell, 'tmpdir', None) is not None:
self.context.call_no_reply(
ansible_mitogen.target.prune_tree,
self._shell.tmpdir,
)
self._shell.tmpdir = None
def _connect(self): def _connect(self):
""" """
Establish a connection to the master process's UNIX listener socket, Establish a connection to the master process's UNIX listener socket,
@ -727,38 +741,53 @@ class Connection(ansible.plugins.connection.ConnectionBase):
stack = self._build_stack() stack = self._build_stack()
self._connect_stack(stack) self._connect_stack(stack)
def close(self, new_task=False): def _reset(self, mode):
""" """
Arrange for the mitogen.master.Router running in the worker to Forget everything we know about the connected context.
gracefully shut down, and wait for shutdown to complete. Safe to call
multiple times.
"""
if getattr(self._shell, 'tmpdir', None) is not None:
# Avoid CallChain to ensure exception is logged on failure.
self.context.call_no_reply(
ansible_mitogen.target.prune_tree,
self._shell.tmpdir,
)
self._shell.tmpdir = None
if self.context: :param str mode:
self.chain.reset() Name of ContextService method to use to discard the context, either
self.parent.call_service( 'put' or 'reset'.
service_name='ansible_mitogen.services.ContextService', """
method_name='put', if not self.context:
context=self.context return
)
self._reset_tmp_path()
self.chain.reset()
self.parent.call_service(
service_name='ansible_mitogen.services.ContextService',
method_name=mode,
context=self.context
)
self.context = None self.context = None
self.login_context = None self.login_context = None
self.init_child_result = None self.init_child_result = None
self.chain = None self.chain = None
if self.broker and not new_task:
def close(self):
"""
Arrange for the mitogen.master.Router running in the worker to
gracefully shut down, and wait for shutdown to complete. Safe to call
multiple times.
"""
self._reset(mode='put')
if self.broker:
self.broker.shutdown() self.broker.shutdown()
self.broker.join() self.broker.join()
self.broker = None self.broker = None
self.router = None self.router = None
def reset(self):
"""
Explicitly terminate the connection to the remote host. This discards
any local state we hold for the connection, returns the Connection to
the 'disconnected' state, and informs ContextService the connection is
bad somehow, and should be shut down and discarded.
"""
self._connect()
self._reset(mode='reset')
def get_chain(self, use_login=False, use_fork=False): def get_chain(self, use_login=False, use_fork=False):
""" """
Return the :class:`mitogen.parent.CallChain` to use for executing Return the :class:`mitogen.parent.CallChain` to use for executing