Auto cleanup of async cache file (#73760)

* Auto cleanup of async cache file

* Add changelog
This commit is contained in:
David Shrewsbury 2021-03-04 14:06:27 -05:00 committed by GitHub
parent a165c72073
commit 78d3810fdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 0 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- Automatically remove async cache files for polled async tasks that have completed (issue https://github.com/ansible/ansible/issues/73206).

View file

@ -62,6 +62,10 @@ To avoid timeouts on a task, specify its maximum runtime and how frequently you
task when run in check mode. See :ref:`check_mode_dry` on how to task when run in check mode. See :ref:`check_mode_dry` on how to
skip a task in check mode. skip a task in check mode.
.. note::
When an async task completes with polling enabled, the temporary async job cache
file (by default in ~/.ansible_async/) is automatically removed.
Run tasks concurrently: poll = 0 Run tasks concurrently: poll = 0
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -87,6 +91,11 @@ To run a playbook task asynchronously::
.. note:: .. note::
Using a higher value for ``--forks`` will result in kicking off asynchronous tasks even faster. This also increases the efficiency of polling. Using a higher value for ``--forks`` will result in kicking off asynchronous tasks even faster. This also increases the efficiency of polling.
.. note::
When running with ``poll: 0``, Ansible will not automatically cleanup the async job cache file.
You will need to manually clean this up with the :ref:`async_status <async_status_module>` module
with ``mode: cleanup``.
If you need a synchronization point with an async task, you can register it to obtain its job ID and use the :ref:`async_status <async_status_module>` module to observe it in a later task. For example:: If you need a synchronization point with an async task, you can register it to obtain its job ID and use the :ref:`async_status <async_status_module>` module to observe it in a later task. For example::
- name: Run an async task - name: Run an async task

View file

@ -795,6 +795,28 @@ class TaskExecutor:
else: else:
return dict(failed=True, msg="async task produced unparseable results", async_result=async_result) return dict(failed=True, msg="async task produced unparseable results", async_result=async_result)
else: else:
# If the async task finished, automatically cleanup the temporary
# status file left behind.
cleanup_task = Task().load(
{
'async_status': {
'jid': async_jid,
'mode': 'cleanup',
},
'environment': self._task.environment,
}
)
cleanup_handler = self._shared_loader_obj.action_loader.get(
'ansible.legacy.async_status',
task=cleanup_task,
connection=self._connection,
play_context=self._play_context,
loader=self._loader,
templar=templar,
shared_loader_obj=self._shared_loader_obj,
)
cleanup_handler.run(task_vars=task_vars)
cleanup_handler.cleanup(force=True)
async_handler.cleanup(force=True) async_handler.cleanup(force=True)
return async_result return async_result

View file

@ -42,6 +42,25 @@
- async_result.finished == 1 - async_result.finished == 1
- async_result is finished - async_result is finished
- name: assert temp async directory exists
stat:
path: "~/.ansible_async"
register: dir_st
- assert:
that:
- dir_st.stat.isdir is defined and dir_st.stat.isdir
- name: stat temp async status file
stat:
path: "~/.ansible_async/{{ async_result.ansible_job_id }}"
register: tmp_async_file_st
- name: validate automatic cleanup of temp async status file on completed run
assert:
that:
- not tmp_async_file_st.stat.exists
- name: test async without polling - name: test async without polling
command: sleep 5 command: sleep 5
async: 30 async: 30