3838import time
3939
4040import jinja2 .runtime
41+ from ansible .module_utils import six
4142import ansible .constants as C
4243import ansible .errors
4344import ansible .plugins .connection
@@ -459,15 +460,10 @@ def call(self, func, *args, **kwargs):
459460
460461
461462class Connection (ansible .plugins .connection .ConnectionBase ):
462- #: mitogen.master.Broker for this worker.
463- broker = None
464-
465- #: mitogen.master.Router for this worker.
466- router = None
467-
468- #: mitogen.parent.Context representing the parent Context, which is
469- #: presently always the connection multiplexer process.
470- parent = None
463+ #: The :class:`ansible_mitogen.process.Binding` representing the connection
464+ #: multiplexer this connection's target is assigned to. :data:`None` when
465+ #: disconnected.
466+ binding = None
471467
472468 #: mitogen.parent.Context for the target account on the target, possibly
473469 #: reached via become.
@@ -518,13 +514,6 @@ class Connection(ansible.plugins.connection.ConnectionBase):
518514 #: matching vanilla Ansible behaviour.
519515 loader_basedir = None
520516
521- def __init__ (self , play_context , new_stdin , ** kwargs ):
522- assert ansible_mitogen .process .MuxProcess .unix_listener_path , (
523- 'Mitogen connection types may only be instantiated '
524- 'while the "mitogen" strategy is active.'
525- )
526- super (Connection , self ).__init__ (play_context , new_stdin )
527-
528517 def __del__ (self ):
529518 """
530519 Ansible cannot be trusted to always call close() e.g. the synchronize
@@ -585,6 +574,15 @@ def homedir(self):
585574 self ._connect ()
586575 return self .init_child_result ['home_dir' ]
587576
577+ def get_binding (self ):
578+ """
579+ Return the :class:`ansible_mitogen.process.Binding` representing the
580+ process that hosts the physical connection and services (context
581+ establishment, file transfer, ..) for our desired target.
582+ """
583+ assert self .binding is not None
584+ return self .binding
585+
588586 @property
589587 def connected (self ):
590588 return self .context is not None
@@ -672,33 +670,21 @@ def _stack_from_spec(self, spec, stack=(), seen_names=()):
672670
673671 return stack
674672
675- def _connect_broker (self ):
676- """
677- Establish a reference to the Broker, Router and parent context used for
678- connections.
679- """
680- if not self .broker :
681- self .broker = mitogen .master .Broker ()
682- self .router , self .parent = mitogen .unix .connect (
683- path = ansible_mitogen .process .MuxProcess .unix_listener_path ,
684- broker = self .broker ,
685- )
686-
687673 def _build_stack (self ):
688674 """
689675 Construct a list of dictionaries representing the connection
690676 configuration between the controller and the target. This is
691677 additionally used by the integration tests "mitogen_get_stack" action
692678 to fetch the would-be connection configuration.
693679 """
694- return self ._stack_from_spec (
695- ansible_mitogen .transport_config .PlayContextSpec (
696- connection = self ,
697- play_context = self ._play_context ,
698- transport = self .transport ,
699- inventory_name = self .inventory_hostname ,
700- )
680+ spec = ansible_mitogen .transport_config .PlayContextSpec (
681+ connection = self ,
682+ play_context = self ._play_context ,
683+ transport = self .transport ,
684+ inventory_name = self .inventory_hostname ,
701685 )
686+ stack = self ._stack_from_spec (spec )
687+ return spec .inventory_name (), stack
702688
703689 def _connect_stack (self , stack ):
704690 """
@@ -711,7 +697,8 @@ def _connect_stack(self, stack):
711697 description of the returned dictionary.
712698 """
713699 try :
714- dct = self .parent .call_service (
700+ dct = mitogen .service .call (
701+ call_context = self .binding .get_service_context (),
715702 service_name = 'ansible_mitogen.services.ContextService' ,
716703 method_name = 'get' ,
717704 stack = mitogen .utils .cast (list (stack )),
@@ -758,8 +745,9 @@ def _connect(self):
758745 if self .connected :
759746 return
760747
761- self ._connect_broker ()
762- stack = self ._build_stack ()
748+ inventory_name , stack = self ._build_stack ()
749+ worker_model = ansible_mitogen .process .get_worker_model ()
750+ self .binding = worker_model .get_binding (inventory_name )
763751 self ._connect_stack (stack )
764752
765753 def _mitogen_reset (self , mode ):
@@ -776,7 +764,8 @@ def _mitogen_reset(self, mode):
776764 return
777765
778766 self .chain .reset ()
779- self .parent .call_service (
767+ mitogen .service .call (
768+ call_context = self .binding .get_service_context (),
780769 service_name = 'ansible_mitogen.services.ContextService' ,
781770 method_name = mode ,
782771 context = self .context
@@ -787,35 +776,16 @@ def _mitogen_reset(self, mode):
787776 self .init_child_result = None
788777 self .chain = None
789778
790- def _shutdown_broker (self ):
791- """
792- Shutdown the broker thread during :meth:`close` or :meth:`reset`.
793- """
794- if self .broker :
795- self .broker .shutdown ()
796- self .broker .join ()
797- self .broker = None
798- self .router = None
799-
800- # #420: Ansible executes "meta" actions in the top-level process,
801- # meaning "reset_connection" will cause :class:`mitogen.core.Latch`
802- # FDs to be cached and erroneously shared by children on subsequent
803- # WorkerProcess forks. To handle that, call on_fork() to ensure any
804- # shared state is discarded.
805- # #490: only attempt to clean up when it's known that some
806- # resources exist to cleanup, otherwise later __del__ double-call
807- # to close() due to GC at random moment may obliterate an unrelated
808- # Connection's resources.
809- mitogen .fork .on_fork ()
810-
811779 def close (self ):
812780 """
813781 Arrange for the mitogen.master.Router running in the worker to
814782 gracefully shut down, and wait for shutdown to complete. Safe to call
815783 multiple times.
816784 """
817785 self ._mitogen_reset (mode = 'put' )
818- self ._shutdown_broker ()
786+ if self .binding :
787+ self .binding .close ()
788+ self .binding = None
819789
820790 def _reset_find_task_vars (self ):
821791 """
@@ -853,7 +823,8 @@ def reset(self):
853823
854824 self ._connect ()
855825 self ._mitogen_reset (mode = 'reset' )
856- self ._shutdown_broker ()
826+ self .binding .close ()
827+ self .binding = None
857828
858829 # Compatibility with Ansible 2.4 wait_for_connection plug-in.
859830 _reset = reset
@@ -1024,7 +995,8 @@ def put_file(self, in_path, out_path):
1024995 utimes = (st .st_atime , st .st_mtime ))
1025996
1026997 self ._connect ()
1027- self .parent .call_service (
998+ mitogen .service .call (
999+ call_context = self .binding .get_service_context (),
10281000 service_name = 'mitogen.service.FileService' ,
10291001 method_name = 'register' ,
10301002 path = mitogen .utils .cast (in_path )
@@ -1036,7 +1008,7 @@ def put_file(self, in_path, out_path):
10361008 # file alive, but that requires more work.
10371009 self .get_chain ().call (
10381010 ansible_mitogen .target .transfer_file ,
1039- context = self .parent ,
1011+ context = self .binding . get_child_service_context () ,
10401012 in_path = in_path ,
10411013 out_path = out_path
10421014 )
0 commit comments