ansible: preload built-in modules in ModuleDepScanner.

For "ansible -m setup" over a 25ms link, avoids 65 roundtrips and
reduces runtime from 5.7s to 4.1s (-28%).

For "ansible -m setup" over a simulated 250 ms link, reduces runtime
from m27.015s to 0m8.254s (-69%).
pull/262/head
David Wilson 8 years ago
parent b577a11f86
commit fdbd954113

@ -313,6 +313,7 @@ class ActionModuleMixin(ansible.plugins.action.ActionBase):
env = {} env = {}
self._compute_environment_string(env) self._compute_environment_string(env)
self._connection._connect()
return ansible_mitogen.planner.invoke( return ansible_mitogen.planner.invoke(
ansible_mitogen.planner.Invocation( ansible_mitogen.planner.Invocation(
action=self, action=self,

@ -181,7 +181,6 @@ class BinaryPlanner(Planner):
return module_common._is_binary(invocation.module_source) return module_common._is_binary(invocation.module_source)
def _grant_file_service_access(self, invocation): def _grant_file_service_access(self, invocation):
invocation.connection._connect()
invocation.connection.parent.call_service( invocation.connection.parent.call_service(
service_name='ansible_mitogen.services.FileService', service_name='ansible_mitogen.services.FileService',
method_name='register', method_name='register',
@ -297,7 +296,6 @@ class NewStylePlanner(ScriptPlanner):
) )
def get_module_utils(self, invocation): def get_module_utils(self, invocation):
invocation.connection._connect()
return invocation.connection.parent.call_service( return invocation.connection.parent.call_service(
service_name='ansible_mitogen.services.ModuleDepService', service_name='ansible_mitogen.services.ModuleDepService',
method_name='scan', method_name='scan',
@ -306,6 +304,7 @@ class NewStylePlanner(ScriptPlanner):
module_path=invocation.module_path, module_path=invocation.module_path,
search_path=self.get_search_path(invocation), search_path=self.get_search_path(invocation),
builtin_path=module_common._MODULE_UTILS_PATH, builtin_path=module_common._MODULE_UTILS_PATH,
context=invocation.connection.context,
) )
def plan(self, invocation): def plan(self, invocation):

@ -624,32 +624,50 @@ class ModuleDepService(mitogen.service.Service):
self._file_service = file_service self._file_service = file_service
self._cache = {} self._cache = {}
def _get_builtin_names(self, builtin_path, resolved):
return [
fullname
for fullname, path, is_pkg in resolved
if os.path.abspath(path).startswith(builtin_path)
]
def _get_custom_tups(self, builtin_path, resolved):
return [
(fullname, path, is_pkg)
for fullname, path, is_pkg in resolved
if not os.path.abspath(path).startswith(builtin_path)
]
@mitogen.service.expose(policy=mitogen.service.AllowParents()) @mitogen.service.expose(policy=mitogen.service.AllowParents())
@mitogen.service.arg_spec({ @mitogen.service.arg_spec({
'module_name': basestring, 'module_name': basestring,
'module_path': basestring, 'module_path': basestring,
'search_path': tuple, 'search_path': tuple,
'builtin_path': basestring, 'builtin_path': basestring,
'context': mitogen.core.Context,
}) })
def scan(self, module_name, module_path, search_path, builtin_path): def scan(self, module_name, module_path, search_path, builtin_path, context):
if (module_name, search_path) not in self._cache: key = (module_name, search_path)
if key not in self._cache:
resolved = ansible_mitogen.module_finder.scan( resolved = ansible_mitogen.module_finder.scan(
module_name=module_name, module_name=module_name,
module_path=module_path, module_path=module_path,
search_path=tuple(search_path) + (builtin_path,), search_path=tuple(search_path) + (builtin_path,),
) )
builtin_path = os.path.abspath(builtin_path) builtin_path = os.path.abspath(builtin_path)
filtered = [ builtin = self._get_builtin_names(builtin_path, resolved)
(fullname, path, is_pkg) custom = self._get_custom_tups(builtin_path, resolved)
for fullname, path, is_pkg in resolved self._cache[key] = {
if not os.path.abspath(path).startswith(builtin_path) 'builtin': builtin,
] 'custom': custom,
self._cache[module_name, search_path] = filtered }
# Grant FileService access to paths in here to avoid another 2 IPCs # Grant FileService access to paths in here to avoid another 2 IPCs
# from WorkerProcess. # from WorkerProcess.
self._file_service.register(path=module_path) self._file_service.register(path=module_path)
for fullname, path, is_pkg in filtered: for fullname, path, is_pkg in custom:
self._file_service.register(path=path) self._file_service.register(path=path)
return self._cache[module_name, search_path] for name in self._cache[key]['builtin']:
self.router.responder.forward_module(context, name)
return self._cache[key]['custom']

Loading…
Cancel
Save