2018-04-20 21:17:02 +02:00
.. _playbooks_async:
2013-09-30 01:03:51 +02:00
Asynchronous Actions and Polling
================================
By default tasks in playbooks block, meaning the connections stay open
until the task is done on each node. This may not always be desirable, or you may
be running operations that take longer than the SSH timeout.
2018-02-13 16:23:55 +01:00
To avoid blocking or timeout issues, you can use asynchronous mode to run all of your tasks at once and then poll until they are done.
2013-09-30 01:03:51 +02:00
2019-04-26 00:23:13 +02:00
The behaviour of asynchronous mode depends on the value of `poll` .
Avoid connection timeouts: poll > 0
-----------------------------------
When `` poll `` is a positive value, the playbook will *still* block on the task until it either completes, fails or times out.
In this case, however, `async` explicitly sets the timeout you wish to apply to this task rather than being limited by the connection method timeout.
2013-09-30 01:03:51 +02:00
To launch a task asynchronously, specify its maximum runtime
and how frequently you would like to poll for status. The default
2019-04-26 00:23:13 +02:00
poll value is 15 seconds if you do not specify a value for `poll` ::
2013-09-30 01:03:51 +02:00
---
2014-02-28 20:18:44 +01:00
2013-09-30 01:03:51 +02:00
- hosts: all
remote_user: root
2014-02-28 20:18:44 +01:00
2013-09-30 01:03:51 +02:00
tasks:
2014-02-28 20:18:44 +01:00
2014-06-12 09:12:52 +02:00
- name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
2013-09-30 01:03:51 +02:00
command: /bin/sleep 15
async: 45
poll: 5
.. note ::
There is no default for the async time limit. If you leave off the
'async' keyword, the task runs synchronously, which is Ansible's
default.
2018-11-29 16:33:43 +01:00
.. note ::
As of Ansible 2.3, async does not support check mode and will fail the
task when run in check mode. See :doc: `playbooks_checkmode` on how to
skip a task in check mode.
2019-04-26 00:23:13 +02:00
Concurrent tasks: poll = 0
--------------------------
When `` poll `` is 0, Ansible will start the task and immediately move on to the next one without waiting for a result.
From the point of view of sequencing this is asynchronous programming: tasks may now run concurrently.
The playbook run will end without checking back on async tasks.
The async tasks will run until they either complete, fail or timeout according to their `async` value.
If you need a synchronization point with a task, register it to obtain its job ID and use the :ref: `async_status <async_status_module>` module to observe it.
You may run a task asynchronously by specifying a poll value of 0::
2013-09-30 01:03:51 +02:00
---
2014-02-28 20:18:44 +01:00
2013-09-30 01:03:51 +02:00
- hosts: all
remote_user: root
2014-02-28 20:18:44 +01:00
2013-09-30 01:03:51 +02:00
tasks:
2014-02-28 20:18:44 +01:00
2014-06-12 09:12:52 +02:00
- name: simulate long running op, allow to run for 45 sec, fire and forget
2013-09-30 01:03:51 +02:00
command: /bin/sleep 15
async: 45
poll: 0
.. note ::
2019-03-04 14:16:09 +01:00
You shouldn't attempt run a task asynchronously by specifying a poll value of 0 with operations that require
2017-11-14 03:32:37 +01:00
exclusive locks (such as yum transactions) if you expect to run other
2013-09-30 01:03:51 +02:00
commands later in the playbook against those same resources.
.. note ::
Using a higher value for `` --forks `` will result in kicking off asynchronous
tasks even faster. This also increases the efficiency of polling.
2018-04-16 02:32:11 +02:00
If you would like to perform a task asynchronously and check on it later you can perform a task similar to the
2014-05-21 03:28:14 +02:00
following::
2017-11-14 03:32:37 +01:00
---
2014-09-26 02:16:41 +02:00
# Requires ansible 1.8+
2017-11-14 03:32:37 +01:00
- name: 'YUM - async task'
yum:
name: docker-io
2018-10-31 15:36:35 +01:00
state: present
2014-05-21 03:28:14 +02:00
async: 1000
poll: 0
register: yum_sleeper
2017-11-14 03:32:37 +01:00
- name: 'YUM - check on async task'
async_status:
jid: "{{ yum_sleeper.ansible_job_id }}"
2014-05-21 03:28:14 +02:00
register: job_result
until: job_result.finished
retries: 30
.. note ::
2017-11-14 03:32:37 +01:00
If the value of `` async: `` is not high enough, this will cause the
2014-05-21 03:28:14 +02:00
"check on it later" task to fail because the temporary status file that
2017-11-14 03:32:37 +01:00
the `` async_status: `` is looking for will not have been written or no longer exist
2013-10-05 18:31:16 +02:00
2017-08-18 22:02:35 +02:00
If you would like to run multiple asynchronous tasks while limiting the amount
of tasks running concurrently, you can do it this way::
#####################
# main.yml
#####################
- name: Run items asynchronously in batch of two items
vars:
sleep_durations:
- 1
- 2
- 3
- 4
- 5
durations: "{{ item }}"
2017-09-17 20:02:46 +02:00
include_tasks: execute_batch.yml
2019-01-24 23:09:41 +01:00
loop: "{{ sleep_durations | batch(2) | list }}"
2017-08-18 22:02:35 +02:00
#####################
# execute_batch.yml
#####################
- name: Async sleeping for batched_items
command: sleep {{ async_item }}
async: 45
poll: 0
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
loop: "{{ durations }}"
2017-08-18 22:02:35 +02:00
loop_control:
loop_var: "async_item"
register: async_results
- name: Check sync status
async_status:
jid: "{{ async_result_item.ansible_job_id }}"
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
loop: "{{ async_results.results }}"
2017-08-18 22:02:35 +02:00
loop_control:
loop_var: "async_result_item"
register: async_poll_results
until: async_poll_results.finished
retries: 30
2013-10-05 18:31:16 +02:00
.. seealso ::
:doc: `playbooks`
An introduction to playbooks
2018-07-21 15:48:47 +02:00
`User Mailing List <https://groups.google.com/group/ansible-devel> `_
2013-10-05 18:31:16 +02:00
Have a question? Stop by the google group!
`irc.freenode.net <http://irc.freenode.net> `_
#ansible IRC chat channel