# Async task / queue management

**URL:** <https://forum.ansible.com/t/async-task-queue-management/2296>\
**Category:** Get Help\
**Tags:** playbook, async\
**Created:** [November 10, 2023, 9:44pm UTC](https://forum.ansible.com/t/async-task-queue-management/2296 "2023-11-10T21:44:18Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![flowerysong](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/flowerysong/32/2305_2.png) [@flowerysong](https://forum.ansible.com/u/flowerysong)\
**Post date:** [November 11, 2023, 7:30pm UTC](https://forum.ansible.com/t/async-task-queue-management/2296/3 "2023-11-11T19:30:40Z")

</div>

`until` can’t be used on `include_tasks`, but that doesn’t mean you can’t redo `include_tasks` until a condition is true. You just have to use tail recursion.

`test.yml`:

```yaml
- hosts: localhost
  gather_facts: false
  tasks:
    - ansible.builtin.set_fact:
        queued_tasks: "{{ range(0, 45, 5) | zip(range(45, 0, -5)) | flatten }}"
        queue_start: "{{ lookup('pipe', 'date +%s') | int }}"

    - ansible.builtin.include_tasks:
        file: tq.yml

```

`tq.yml`:

```yaml
- when: (running_tasks | default([]) | length < 3) and (queued_tasks | length > 0)
  block:
    - name: Launch a new task
      ansible.builtin.command: sleep {{ queued_tasks[0] }}
      async: 60
      poll: 0
      register: result

    - ansible.builtin.debug:
        msg: Launched {{ queued_tasks[0] }} at {{ (lookup('pipe', 'date +%s') | int) - queue_start }}

    - name: Move launched task between queues
      ansible.builtin.set_fact:
        queued_tasks: "{{ queued_tasks[1:] }}"
        running_tasks: "{{ running_tasks | default([]) | union([result.ansible_job_id]) }}"

# consider adding a sleep here to make the loop less busy
# - ansible.builtin.wait_for:
# timeout: 5
# when: running_tasks | length >= 3

- name: Check on tasks
  ansible.builtin.async_status:
    jid: "{{ item }}"
  register: result
  loop: "{{ running_tasks }}"

- name: Remove finished tasks from check queue
  ansible.builtin.set_fact:
    running_tasks: "{{ result.results | rejectattr('finished') | map(attribute='item') }}"

- name: Run again if needed
  ansible.builtin.include_tasks:
    file: tq.yml
  when: (queued_tasks | length > 0) or (running_tasks | length > 0)

```

Output:

```auto
$ ansible-playbook test.yml | grep Launched
    msg: Launched 0 at 1
    msg: Launched 45 at 2
    msg: Launched 5 at 3
    msg: Launched 40 at 5
    msg: Launched 10 at 10
    msg: Launched 35 at 24
    msg: Launched 15 at 48
    msg: Launched 30 at 50
    msg: Launched 20 at 62
    msg: Launched 25 at 65
    msg: Launched 25 at 85
    msg: Launched 20 at 89
    msg: Launched 30 at 95
    msg: Launched 15 at 112
    msg: Launched 35 at 115
    msg: Launched 10 at 128
    msg: Launched 40 at 131
    msg: Launched 5 at 143

```

---

_[View the full topic](https://forum.ansible.com/t/async-task-queue-management/2296)._
