Answers: <blockquote>
  <p>Order of execution is important Server (Task A) needs to run before the client (Task B)</p>
  </blockquote>
  <p>Then why are your running Task A async in that case ? Is it just because <code>iperf --server</code> is not falling in the background and dying as soon as the shell task finishes ? A quick look at the <a href="https://iperf.fr/iperf-doc.php#3doc" rel="nofollow noreferrer">documentation</a> shows we can probably work around that problem with something like:</p>
  <pre class="lang-bash prettyprint-override"><code>iperf3 --server --daemon --pidfile /path/to/iperf3.pid --logfile /path/to/log
  </code></pre>
  <p>Notes:</p>
  <ul>
  <li>I added the <code>logfile</code> option since I guess it can be useful but it is not mandatory for the current issue</li>
  <li>I took for granted you are running the server on a linux platform. Running it on Windows would apparently slightly change the below scenario. See <a href="https://iperf.fr/iperf-doc.php#service" rel="nofollow noreferrer">Running as a service on windows</a></li>
  </ul>
  <p>From what I understand the last unsolved issue is running the client tasks sequentially on each client host. This can be done using the <a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_strategies.html#rolling-update-batch-size" rel="nofollow noreferrer"><code>serial</code> keyword</a> on your play.</p>
  <p>Here is an untested pseudo ansible setup summarizing what I understand from your requirements. Adapt to your real use-case.</p>
  <p><strong><code>inventory/iperf_hosts.yml</code></strong></p>
  <pre class="lang-yaml prettyprint-override"><code>---
  iperf_servers:
    vars:
      iperf_pid_file: /tmp/iperf.pid
      iperf_log_file: /tmp/iperf.log
    hosts:
      server1.local:
  iperf_clients:
    vars:
      iperf_time: 1
      iperf_dest: some\win\directory
    hosts:
      host1.local:
      host2.local:
      host3.local:
  </code></pre>
  <p><strong><code>playbook.yml</code></strong></p>
  <pre class="lang-yaml prettyprint-override"><code>---
  - name: Start the iperf server
    hosts: iperf_servers
    
    tasks:
      - name: Fire the start command
        command: &quot;iperf3 --server --daemon --pidfile {{ iperf_pid_file }} --logfile {{ iperf_log_file }}&quot;
  
  - name: Launch clients one after the other.
    hosts: iperf_clients
    serial: 1
    
    tasks:
      - name: Run iperf3 client
        win_command: &quot;iperf3 -c {{ hostvars[group['iperf_servers'][0]].inventory_hostname }} -t {{ iperf_time }}&quot;
        args:
          chdir: &quot;{{ iperf_dest }}&quot;
        register: iperf3_out
  
      - debug:
          var: iperf3_out.stdout
  
  - name: Now we are over with clients, kill the server
    hosts: iperf_servers
    # We already gathered facts at first play so we disable here
    # You might want to disable in all other plays if you don't need facts at all
    gather_facts: false
  
    tasks:
      - name: Slurp pid from file
        slurp:
          path: &quot;{{ iperf_pid_file }}&quot;
        register: slurped_pid
  
      - name: kill the iperf3 process
        command: &quot;kill {{ slurped_pid.content | b64decode }}&quot;
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2021-03-28T23:49:46.087Z
Answers: 2021-04-08T07:15:11.200Z
Answers: 2021-04-08T07:15:11.200Z
Answers: Zeitounator
Body: <p>I'm trying to run two simple tasks</p>
  <p><code>Task A</code> starts an Ipref3 server and waits for a client to connect<br />
  <code>Task B</code> starts to run from <em>host-1</em> until the given timeout</p>
  <p>once <code>Task B (host-1)</code> is over another <code>Task B</code> run from host-2</p>
  <p><code>Task B</code> starts to run from <em>host-2</em> until the given timeout</p>
  <p>What is a good approach to orchestrating this use-case?</p>
  <p><strong>This is what I tried</strong></p>
  <p><code>Task B</code> runs the client from multiple hosts (host-1, host-2, ..)</p>
  <pre><code>- name: Run iperf3 client
    win_command: iperf3 -c {{ iperf_server }} -t {{ iperf_time }} 
    args:
      chdir: &quot;{{ iperf_dest }}&quot;
    register: iperf3_out
  
  - debug:
      var: iperf3_out.stdout
  </code></pre>
  <p><code>Task A</code> run the server</p>
  <pre><code>- name: Start iperf3 server
    shell: iperf3 --server
    async: &quot;{{ iperf_async }}&quot; # iperf_async = iperf_time + 10
    poll: &quot;{{ iperf_poll }}&quot;   # iperf_poll  = 0  
  </code></pre>
  <p>Is there a way to know when to confirm <code>Task A</code> is finished before I move to the next task.</p>
  <p>NOTE: Order of execution is important Server (<code>Task A</code>) needs to run before the client (<code>Task B</code>)</p>
  
Tags: <ansible><automation>
Title: Problem with Ansible Asynchronous actions
UserDisplayName: Hanoch
ThreadText: # Problem with Ansible Asynchronous actions
  
  (Asked by: username_0 on 2021-03-15)
  
  I'm trying to run two simple tasks
  
  `Task A` starts an Ipref3 server and waits for a client to connect  
  `Task B` starts to run from *host-1* until the given timeout
  
  once `Task B (host-1)` is over another `Task B` run from host-2
  
  `Task B` starts to run from *host-2* until the given timeout
  
  What is a good approach to orchestrating this use-case?
  
  **This is what I tried**
  
  `Task B` runs the client from multiple hosts (host-1, host-2, ..)
  
  ```
  - name: Run iperf3 client
    win_command: iperf3 -c {{ iperf_server }} -t {{ iperf_time }} 
    args:
      chdir: "{{ iperf_dest }}"
    register: iperf3_out
  
  - debug:
      var: iperf3_out.stdout
  
  ```
  
  `Task A` run the server
  
  ```
  - name: Start iperf3 server
    shell: iperf3 --server
    async: "{{ iperf_async }}" # iperf_async = iperf_time + 10
    poll: "{{ iperf_poll }}"   # iperf_poll  = 0  
  
  ```
  
  Is there a way to know when to confirm `Task A` is finished before I move to the next task.
  
  NOTE: Order of execution is important Server (`Task A`) needs to run before the client (`Task B`)
  
  **Tags:** ansible, automation
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2021-03-28. Score: 1 | Accepted answer
  
  > Order of execution is important Server (Task A) needs to run before the client (Task B)
  
  Then why are your running Task A async in that case ? Is it just because `iperf --server` is not falling in the background and dying as soon as the shell task finishes ? A quick look at the [documentation](https://iperf.fr/iperf-doc.php#3doc) shows we can probably work around that problem with something like:
  
  ```bash
  iperf3 --server --daemon --pidfile /path/to/iperf3.pid --logfile /path/to/log
  
  ```
  
  Notes:
  
  * I added the `logfile` option since I guess it can be useful but it is not mandatory for the current issue
  * I took for granted you are running the server on a linux platform. Running it on Windows would apparently slightly change the below scenario. See [Running as a service on windows](https://iperf.fr/iperf-doc.php#service)
  
  From what I understand the last unsolved issue is running the client tasks sequentially on each client host. This can be done using the [`serial` keyword](https://docs.ansible.com/ansible/latest/user_guide/playbooks_strategies.html#rolling-update-batch-size) on your play.
  
  Here is an untested pseudo ansible setup summarizing what I understand from your requirements. Adapt to your real use-case.
  
  **`inventory/iperf_hosts.yml`**
  
  ```yaml
  ---
  iperf_servers:
    vars:
      iperf_pid_file: /tmp/iperf.pid
      iperf_log_file: /tmp/iperf.log
    hosts:
      server1.local:
  iperf_clients:
    vars:
      iperf_time: 1
      iperf_dest: some\win\directory
    hosts:
      host1.local:
      host2.local:
      host3.local:
  
  ```
  
  **`playbook.yml`**
  
  ```yaml
  ---
  - name: Start the iperf server
    hosts: iperf_servers
    
    tasks:
      - name: Fire the start command
        command: "iperf3 --server --daemon --pidfile {{ iperf_pid_file }} --logfile {{ iperf_log_file }}"
  
  - name: Launch clients one after the other.
    hosts: iperf_clients
    serial: 1
    
    tasks:
      - name: Run iperf3 client
        win_command: "iperf3 -c {{ hostvars[group['iperf_servers'][0]].inventory_hostname }} -t {{ iperf_time }}"
        args:
          chdir: "{{ iperf_dest }}"
        register: iperf3_out
  
      - debug:
          var: iperf3_out.stdout
  
  - name: Now we are over with clients, kill the server
    hosts: iperf_servers
    # We already gathered facts at first play so we disable here
    # You might want to disable in all other plays if you don't need facts at all
    gather_facts: false
  
    tasks:
      - name: Slurp pid from file
        slurp:
          path: "{{ iperf_pid_file }}"
        register: slurped_pid
  
      - name: kill the iperf3 process
        command: "kill {{ slurped_pid.content | b64decode }}"
  
  ```
  
  
  ---
  
  