Matt,
Could you share your benchmark. I'm seeing barely any difference
With lock:
± hyperfine -- "ansible-playbook --forks 25 -i 100_hosts.yml 100_debugs.yml"
Benchmark #1: ansible-playbook --forks 25 -i 100_hosts.yml 100_debugs.yml
Time (mean ± σ): 6.744 s ± 0.107 s [User: 27.194 s, System: 1.963 s]
Range (min … max): 6.537 s … 6.829 s 10 runs
Without lock
$ hyperfine -- "ansible-playbook --forks 25 -i 100_hosts.yml 100_debugs.yml"
Benchmark #1: ansible-playbook --forks 25 -i 100_hosts.yml 100_debugs.yml
Time (mean ± σ): 6.675 s ± 0.090 s [User: 27.160 s, System: 1.936 s]
Range (min … max): 6.499 s … 6.748 s 10 runs
$ git rev-parse HEAD
c4e211a4291162c17054f44ad5381856ffff802f
$ git diff | cat
diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py
index 70dea1ea6f..31e0f58eb5 100644
--- a/lib/ansible/plugins/strategy/__init__.py
+++ b/lib/ansible/plugins/strategy/__init__.py
@@ -101,14 +101,13 @@ def results_thread_main(strategy):
strategy._tqm.send_callback(result.method_name, *result.args, **result.kwargs)
elif isinstance(result, TaskResult):
strategy.normalize_task_result(result)
- with strategy._results_lock:
- # only handlers have the listen attr, so this must be a handler
- # we split up the results into two queues here to make sure
- # handler and regular result processing don't cross wires
- if 'listen' in result._task_fields:
- strategy._handler_results.append(result)
- else:
- strategy._results.append(result)
+ # only handlers have the listen attr, so this must be a handler
+ # we split up the results into two queues here to make sure
+ # handler and regular result processing don't cross wires
+ if 'listen' in result._task_fields:
+ strategy._handler_results.append(result)
+ else:
+ strategy._results.append(result)
else:
display.warning('Received an invalid object (%s) in the result queue: %r' % (type(result), result))
except (IOError, EOFError):
@@ -223,7 +222,6 @@ class StrategyBase:
self._results = deque()
self._handler_results = deque()
- self._results_lock = threading.Condition(threading.Lock())
# create the result processing thread for reading results in the background
self._results_thread = threading.Thread(target=results_thread_main, args=(self,))
@@ -524,15 +522,12 @@ class StrategyBase:
cur_pass = 0
while True:
try:
- self._results_lock.acquire()
if do_handlers:
task_result = self._handler_results.popleft()
else:
task_result = self._results.popleft()
except IndexError:
break
- finally:
- self._results_lock.release()
original_host = task_result._host
original_task = task_result._task
$ cat 100_hosts.yml
all:
hosts:
local[001:100]:
vars:
ansible_connection: local
$ cat 100_debugs.yml
- hosts: all
gather_facts: false
tasks:
- debug:
loop: "{{ range(100) }}"