mirror of https://github.com/ansible/ansible.git
Allow callbacks from forks (#70501)
* POC for supporting callback events that come from the worker * linting fixes. ci_complete * fix up units. ci_complete * Try moving the sentinel put higher. ci_complete * safeguards. ci_complete * Move queue killing to terminate * LINTING. ci_complete * Subclass Queue, to add helper send_callback method * Just use _final_q instead of adding another queue and thread * Revert a few changes * Add helper for inserting a TaskResult into the _final_q * Add changelog fragment * Address rebase issue * ci_complete * Add test to assert async poll callback from fork * Don't use full path * ci_complete * Use _results_lock as a context manager * Add new generic lock decorator, and use it with send_callbackpull/71348/head
parent
92d59a58c0
commit
5821128995
@ -0,0 +1,3 @@
|
||||
minor_changes:
|
||||
- callbacks - Add feature allowing forks to send callback events
|
||||
(https://github.com/ansible/ansible/issues/14681)
|
@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2020 Matt Martz <matt@sivel.net>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
# Make coding more python3-ish
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
from functools import wraps
|
||||
|
||||
|
||||
def lock_decorator(attr='missing_lock_attr', lock=None):
|
||||
'''This decorator is a generic implementation that allows you
|
||||
to either use a pre-defined instance attribute as the location
|
||||
of the lock, or to explicitly pass a lock object.
|
||||
|
||||
This code was implemented with ``threading.Lock`` in mind, but
|
||||
may work with other locks, assuming that they function as
|
||||
context managers.
|
||||
|
||||
When using ``attr``, the assumption is the first argument to
|
||||
the wrapped method, is ``self`` or ``cls``.
|
||||
|
||||
Examples:
|
||||
|
||||
@lock_decorator(attr='_callback_lock')
|
||||
def send_callback(...):
|
||||
|
||||
@lock_decorator(lock=threading.Lock())
|
||||
def some_method(...):
|
||||
'''
|
||||
def outer(func):
|
||||
@wraps(func)
|
||||
def inner(*args, **kwargs):
|
||||
# Python2 doesn't have ``nonlocal``
|
||||
# assign the actual lock to ``_lock``
|
||||
if lock is None:
|
||||
_lock = getattr(args[0], attr)
|
||||
else:
|
||||
_lock = lock
|
||||
with _lock:
|
||||
return func(*args, **kwargs)
|
||||
return inner
|
||||
return outer
|
@ -0,0 +1,7 @@
|
||||
- hosts: localhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Async poll callback test
|
||||
command: sleep 5
|
||||
async: 6
|
||||
poll: 1
|
Loading…
Reference in New Issue