ansible: split key_from_dict() out into free function.

This commit is contained in:
David Wilson 2018-10-29 15:27:20 +00:00
parent 53d882dcbd
commit d0f5671887
1 changed files with 22 additions and 20 deletions

View File

@ -89,6 +89,24 @@ def _get_candidate_temp_dirs():
return mitogen.utils.cast(dirs) return mitogen.utils.cast(dirs)
def key_from_dict(**kwargs):
"""
Return a unique string representation of a dict as quickly as possible.
Used to generated deduplication keys from a request.
"""
out = []
stack = [kwargs]
while stack:
obj = stack.pop()
if isinstance(obj, dict):
stack.extend(sorted(obj.items()))
elif isinstance(obj, (list, tuple)):
stack.extend(obj)
else:
out.append(str(obj))
return ''.join(out)
class Error(Exception): class Error(Exception):
pass pass
@ -113,7 +131,7 @@ class ContextService(mitogen.service.Service):
super(ContextService, self).__init__(*args, **kwargs) super(ContextService, self).__init__(*args, **kwargs)
self._lock = threading.Lock() self._lock = threading.Lock()
#: Records the :meth:`get` result dict for successful calls, returned #: Records the :meth:`get` result dict for successful calls, returned
#: for identical subsequent calls. Keyed by :meth:`key_from_kwargs`. #: for identical subsequent calls. Keyed by :meth:`key_from_dict`.
self._response_by_key = {} self._response_by_key = {}
#: List of :class:`mitogen.core.Latch` awaiting the result for a #: List of :class:`mitogen.core.Latch` awaiting the result for a
#: particular key. #: particular key.
@ -126,7 +144,7 @@ class ContextService(mitogen.service.Service):
#: :attr:`max_interpreters` is reached, the most recently used context #: :attr:`max_interpreters` is reached, the most recently used context
#: is destroyed to make room for any additional context. #: is destroyed to make room for any additional context.
self._lru_by_via = {} self._lru_by_via = {}
#: :meth:`key_from_kwargs` result by Context. #: :func:`key_from_dict` result by Context.
self._key_by_context = {} self._key_by_context = {}
@mitogen.service.expose(mitogen.service.AllowParents()) @mitogen.service.expose(mitogen.service.AllowParents())
@ -149,29 +167,13 @@ class ContextService(mitogen.service.Service):
finally: finally:
self._lock.release() self._lock.release()
def key_from_kwargs(self, **kwargs):
"""
Generate a deduplication key from the request.
"""
out = []
stack = [kwargs]
while stack:
obj = stack.pop()
if isinstance(obj, dict):
stack.extend(sorted(obj.items()))
elif isinstance(obj, (list, tuple)):
stack.extend(obj)
else:
out.append(str(obj))
return ''.join(out)
def _produce_response(self, key, response): def _produce_response(self, key, response):
""" """
Reply to every waiting request matching a configuration key with a Reply to every waiting request matching a configuration key with a
response dictionary, deleting the list of waiters when done. response dictionary, deleting the list of waiters when done.
:param str key: :param str key:
Result of :meth:`key_from_kwargs` Result of :meth:`key_from_dict`
:param dict response: :param dict response:
Response dictionary Response dictionary
:returns: :returns:
@ -361,7 +363,7 @@ class ContextService(mitogen.service.Service):
def _wait_or_start(self, spec, via=None): def _wait_or_start(self, spec, via=None):
latch = mitogen.core.Latch() latch = mitogen.core.Latch()
key = self.key_from_kwargs(via=via, **spec) key = key_from_dict(via=via, **spec)
self._lock.acquire() self._lock.acquire()
try: try:
response = self._response_by_key.get(key) response = self._response_by_key.get(key)