commit 964a00230e4ed8257a416d38b96639f862354216
parent 1102ebc98a5e059cb430295a2b62050c70e52b81
Author: Asher Morgan <asher@ashermorgan.net>
Date: Wed, 2 Sep 2026 19:05:33 -0700
Set client keep-alive frequency server-side
Diffstat:
2 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/aoh/client.py b/aoh/client.py
@@ -20,9 +20,6 @@ PASSWORD_PROMPTS = {
'vault_password': 'Vault password: ',
}
-# Set 10s EXEC keep alive interval (see also TIMEOUT in aoh.py)
-KEEP_ALIVE_INTERVAL = 10
-
# How long to sleep after receiving an empty responses
WAIT_INTERVAL = 0.1
@@ -31,7 +28,7 @@ class ClientError(Exception):
"""Raised for miscellaneous client errors."""
-def exec(args, keep_alive_handler=None):
+def exec(args, keep_alive_interval=None, keep_alive_handler=None):
"""Run a command on the local host."""
try:
@@ -45,7 +42,7 @@ def exec(args, keep_alive_handler=None):
while p.returncode is None:
try:
- p.wait(KEEP_ALIVE_INTERVAL)
+ p.wait(keep_alive_interval)
except subprocess.TimeoutExpired:
if keep_alive_handler:
keep_alive_handler()
@@ -158,7 +155,8 @@ def runner_loop(runner_url, cookies):
{ 'id': res['id'], 'keep-alive': True },
keep_alive=True
)
- req = exec(res['exec'], keep_alive_handler)
+ req = exec(res['exec'], res['keep-alive-interval'],
+ keep_alive_handler)
req['id'] = res['id']
elif 'put' in res:
req = put(res['put'])
diff --git a/aoh/connection_plugins/aoh.py b/aoh/connection_plugins/aoh.py
@@ -12,6 +12,27 @@ DOCUMENTATION = """
required: true
vars:
- name: ansible_aoh_dir
+ aoh_timeout:
+ description: The timeout for AoH responses, in seconds
+ type: integer
+ default: 60
+ env:
+ - name: ANSIBLE_TIMEOUT
+ ini:
+ - key: timeout
+ section: defaults
+ vars:
+ - name: ansible_aoh_timeout
+ cli:
+ - name: timeout
+ aoh_keep_alive_count:
+ description: The number of keep alive messages expected per timeout
+ type: integer
+ default: 10
+ env:
+ - name: ANSIBLE_AOH_KEEP_ALIVE_COUNT
+ vars:
+ - name: ansible_aoh_keep_alive_count
"""
import base64
@@ -32,9 +53,6 @@ from ansible.utils.display import Display
display = Display()
-# Set 1m timeout (see also KEEP_ALIVE_INTERVAL in client.py)
-TIMEOUT = 60
-
class Connection(ConnectionBase):
"""Ansible-over-HTTP (AoH) connection."""
@@ -46,6 +64,10 @@ class Connection(ConnectionBase):
def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
super().__init__(*args, **kwargs)
+ self.timeout = self.get_option('aoh_timeout')
+ self.keep_alive_count = self.get_option('aoh_keep_alive_count')
+ self.keep_alive_interval = round(self.timeout/self.keep_alive_count, 1)
+
self._sendbuf = None
self._recvbuf = None
self._recvpoll = None
@@ -95,11 +117,12 @@ class Connection(ConnectionBase):
assert self._recvpoll is not None
msg['id'] = str(uuid4())
+ msg['keep-alive-interval'] = self.keep_alive_interval
self._sendbuf.write(json.dumps(msg) + '\n')
self._sendbuf.flush()
while True:
- if not self._recvpoll.poll(TIMEOUT * 1000):
+ if not self._recvpoll.poll(self.timeout * 1000):
raise AnsibleConnectionFailure('Timed out waiting for AoH '
'response')