Skip to content

mitogen randomly complains about broken connections when using synchronize module within a loop #925

Open
@nradchenko

Description

@nradchenko

I see mysterious tracebacks from mitogen appearing in the play output when using synchronize module. Sometimes these tracebacks don't affect the play and things seem to work okay, and sometimes they are followed by "An exception occurred during task execution" error from ansible and thus fail the task.

This is the shortest playbook to reproduce the problem I could come up with:

- hosts: all
  gather_facts: no
  tasks:
  - name: copy dummy files
    synchronize:
      src: zero
      dest: /root/{{ item }}
    loop:
      - 1
      - 2
      - 3

So here we have gather_facts: no, 3 elements in a list, a regular file zero (obviously, it has zero length), and the error is usually triggered after the second (!) iteration.

root@59cfe90e2671:~/test# ansible-playbook -i hosts.yml test.yml 

PLAY [all] ************************************************************************************************************************************************************************************

TASK [copy dummy files] ***********************************************************************************************************************************************************************
ok: [vps] => (item=1)
ok: [vps] => (item=2)
Exception ignored in: <function Connection.__del__ at 0x7f6f52fa89d0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 531, in __del__
    self.close()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 884, in close
    self._put_connection()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 865, in _put_connection
    self.chain.reset()
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1852, in reset
    self.call_no_reply(mitogen.core.Dispatcher.forget_chain, saved)
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1907, in call_no_reply
    self.context.send(self.make_msg(fn, *args, **kwargs))
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2310, in send
    self.router.route(msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 3383, in route
    self.broker.defer(self._async_route, msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2864, in defer
    raise Error(self.broker_shutdown_msg)
mitogen.core.Error: An attempt was made to enqueue a message with a Broker that has already exitted. It is likely your program called Broker.shutdown() too early.
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: mitogen.core.Error: An attempt was made to enqueue a message with a Broker that has already exitted. It is likely your program called Broker.shutdown() too early.
fatal: [vps]: FAILED! => {"msg": "Unexpected failure during module execution.", "stdout": ""}

PLAY RECAP ************************************************************************************************************************************************************************************
vps                        : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

root@59cfe90e2671:~/test# ansible-playbook -i hosts.yml test.yml 

PLAY [all] ************************************************************************************************************************************************************************************

TASK [copy dummy files] ***********************************************************************************************************************************************************************
ok: [vps] => (item=1)
ok: [vps] => (item=2)
Exception ignored in: <function Connection.__del__ at 0x7fbef18c89d0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 531, in __del__
    self.close()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 884, in close
    self._put_connection()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 865, in _put_connection
    self.chain.reset()
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1852, in reset
    self.call_no_reply(mitogen.core.Dispatcher.forget_chain, saved)
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1907, in call_no_reply
    self.context.send(self.make_msg(fn, *args, **kwargs))
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2310, in send
    self.router.route(msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 3383, in route
    self.broker.defer(self._async_route, msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2864, in defer
    raise Error(self.broker_shutdown_msg)
mitogen.core.Error: An attempt was made to enqueue a message with a Broker that has already exitted. It is likely your program called Broker.shutdown() too early.
ok: [vps] => (item=3)

PLAY RECAP ************************************************************************************************************************************************************************************
vps                        : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

root@59cfe90e2671:~/test# 

It becomes a bit tricky to get stable errors when using gather_facts: yes, but the general rule is: more items in a loop - more chances to make something go wrong. According to my tests, the following playbook has high chances to fail:

- hosts: all
  gather_facts: yes
  tasks:
  - name: copy dummy files
    synchronize:
      src: zero
      dest: /root/{{ item }}
    loop:
      - 1
      - 2
      - 3
      - 4
      - 5
      - 6
      - 7
      - 8
      - 9
root@59cfe90e2671:~/test# ansible-playbook -i hosts.yml test.yml 

PLAY [all] ************************************************************************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************************************
ok: [vps]

TASK [copy dummy files] ***********************************************************************************************************************************************************************
ok: [vps] => (item=1)
ok: [vps] => (item=2)
ok: [vps] => (item=3)
changed: [vps] => (item=4)
changed: [vps] => (item=5)
changed: [vps] => (item=6)
changed: [vps] => (item=7)
Exception ignored in: <function Connection.__del__ at 0x7f34684089d0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 531, in __del__
    self.close()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 884, in close
    self._put_connection()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 865, in _put_connection
    self.chain.reset()
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1852, in reset
    self.call_no_reply(mitogen.core.Dispatcher.forget_chain, saved)
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1907, in call_no_reply
    self.context.send(self.make_msg(fn, *args, **kwargs))
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2310, in send
    self.router.route(msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 3383, in route
    self.broker.defer(self._async_route, msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2864, in defer
    raise Error(self.broker_shutdown_msg)
mitogen.core.Error: An attempt was made to enqueue a message with a Broker that has already exitted. It is likely your program called Broker.shutdown() too early.
Exception ignored in: <function Connection.__del__ at 0x7f34684089d0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 531, in __del__
    self.close()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 884, in close
    self._put_connection()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 865, in _put_connection
    self.chain.reset()
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1852, in reset
    self.call_no_reply(mitogen.core.Dispatcher.forget_chain, saved)
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1907, in call_no_reply
    self.context.send(self.make_msg(fn, *args, **kwargs))
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2310, in send
    self.router.route(msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 3383, in route
    self.broker.defer(self._async_route, msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2864, in defer
    raise Error(self.broker_shutdown_msg)
mitogen.core.Error: An attempt was made to enqueue a message with a Broker that has already exitted. It is likely your program called Broker.shutdown() too early.
Exception ignored in: <function Connection.__del__ at 0x7f34684089d0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 531, in __del__
    self.close()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 884, in close
    self._put_connection()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 865, in _put_connection
    self.chain.reset()
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1852, in reset
    self.call_no_reply(mitogen.core.Dispatcher.forget_chain, saved)
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1907, in call_no_reply
    self.context.send(self.make_msg(fn, *args, **kwargs))
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2310, in send
    self.router.route(msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 3383, in route
    self.broker.defer(self._async_route, msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2864, in defer
    raise Error(self.broker_shutdown_msg)
mitogen.core.Error: An attempt was made to enqueue a message with a Broker that has already exitted. It is likely your program called Broker.shutdown() too early.
Exception ignored in: <function Connection.__del__ at 0x7f34684089d0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 531, in __del__
    self.close()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 884, in close
    self._put_connection()
  File "/usr/local/lib/python3.10/site-packages/ansible_mitogen/connection.py", line 865, in _put_connection
    self.chain.reset()
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1852, in reset
    self.call_no_reply(mitogen.core.Dispatcher.forget_chain, saved)
  File "/usr/local/lib/python3.10/site-packages/mitogen/parent.py", line 1907, in call_no_reply
    self.context.send(self.make_msg(fn, *args, **kwargs))
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2310, in send
    self.router.route(msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 3383, in route
    self.broker.defer(self._async_route, msg)
  File "/usr/local/lib/python3.10/site-packages/mitogen/core.py", line 2864, in defer
    raise Error(self.broker_shutdown_msg)
mitogen.core.Error: An attempt was made to enqueue a message with a Broker that has already exitted. It is likely your program called Broker.shutdown() too early.
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: mitogen.core.Error: An attempt was made to enqueue a message with a Broker that has already exitted. It is likely your program called Broker.shutdown() too early.
fatal: [vps]: FAILED! => {"msg": "Unexpected failure during module execution.", "stdout": ""}

PLAY RECAP ************************************************************************************************************************************************************************************
vps                        : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

root@59cfe90e2671:~/test# 

It doesn't seem to depend on synchronize params much, as it fails when pointing to nonexistent source file too, or even when rsync is not installed on host machine. I can also reproduce the issue with different ansible (2.8.15, 3.2.0, 4.5.0, 5.7.0) and mitogen (0.2.10) versions, and with python 2.7 on the target, and I couldn't find a combination of recent ansible and mitogen versions which works properly.

Host system:

  • Debian 11 based docker container (python:3.10)
  • Python 3.10.4
  • Ansible 2.10.17
  • Mitogen from master branch

The only lines in my ansible.cfg are:

[defaults]
strategy_plugins = /usr/local/lib/python3.10/site-packages/ansible_mitogen/plugins/strategy
strategy = mitogen_linear

Target system:

  • Ubuntu 22.04 KVM VPS
  • Python 3.10.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    affects-0.3Issues related to 0.3.X Mitogen releasesbugCode feature that hinders desired execution outcome

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions