From 5c721e8a47848543b4e111783235eafff221666c Mon Sep 17 00:00:00 2001 From: Xyon Date: Thu, 23 Jan 2020 20:04:52 +0000 Subject: [PATCH] Add new configuration parameter to make Windows async startup timeout configurable (#66670) * Add new configuration parameter to make this timeout configurable * Rename keys to be more correct and reformat exception message for whitespace handling * Rename config away from default prefix. Add vars element and associated changes to support. * Update 65001-allow_configuring_async_startup_timeout.yml Co-authored-by: Matt Davis --- ...-allow_configuring_async_startup_timeout.yml | 3 +++ lib/ansible/config/base.yml | 17 +++++++++++++++++ .../executor/powershell/async_wrapper.ps1 | 11 ++++++++--- .../executor/powershell/module_manifest.py | 1 + 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/65001-allow_configuring_async_startup_timeout.yml diff --git a/changelogs/fragments/65001-allow_configuring_async_startup_timeout.yml b/changelogs/fragments/65001-allow_configuring_async_startup_timeout.yml new file mode 100644 index 00000000000..f135a0df3ab --- /dev/null +++ b/changelogs/fragments/65001-allow_configuring_async_startup_timeout.yml @@ -0,0 +1,3 @@ +minor_changes: + - Add a new config parameter, WIN_ASYNC_STARTUP_TIMEOUT, which allows configuration of the named pipe connection + timeout under Windows when launching async tasks. diff --git a/lib/ansible/config/base.yml b/lib/ansible/config/base.yml index 90456bbcb40..1a588b747e4 100644 --- a/lib/ansible/config/base.yml +++ b/lib/ansible/config/base.yml @@ -1846,6 +1846,23 @@ VARIABLE_PRECEDENCE: - {key: precedence, section: defaults} type: list version_added: "2.4" +WIN_ASYNC_STARTUP_TIMEOUT: + name: Windows Async Startup Timeout + default: 5 + description: + - For asynchronous tasks in Ansible (covered in Asynchronous Actions and Polling), + this is how long, in seconds, to wait for the task spawned by Ansible to connect back to the named pipe used + on Windows systems. The default is 5 seconds. This can be too low on slower systems, or systems under heavy load. + - This is not the total time an async command can run for, but is a separate timeout to wait for an async command to + start. The task will only start to be timed against its async_timeout once it has connected to the pipe, so the + overall maximum duration the task can take will be extended by the amount specified here. + env: [{name: ANSIBLE_WIN_ASYNC_STARTUP_TIMEOUT}] + ini: + - {key: win_async_startup_timeout, section: defaults} + type: integer + vars: + - {name: ansible_win_async_startup_timeout} + version_added: '2.10' YAML_FILENAME_EXTENSIONS: name: Valid YAML extensions default: [".yml", ".yaml", ".json"] diff --git a/lib/ansible/executor/powershell/async_wrapper.ps1 b/lib/ansible/executor/powershell/async_wrapper.ps1 index 545b4a5623c..93ad52ecbd5 100644 --- a/lib/ansible/executor/powershell/async_wrapper.ps1 +++ b/lib/ansible/executor/powershell/async_wrapper.ps1 @@ -145,11 +145,16 @@ try { $result_json = ConvertTo-Json -InputObject $result -Depth 99 -Compress Set-Content $results_path -Value $result_json - Write-AnsibleLog "INFO - waiting for async process to connect to named pipe for 5 seconds" "async_wrapper" + $np_timeout = $Payload.async_startup_timeout * 1000 + Write-AnsibleLog "INFO - waiting for async process to connect to named pipe for $np_timeout milliseconds" "async_wrapper" $wait_async = $pipe.BeginWaitForConnection($null, $null) - $wait_async.AsyncWaitHandle.WaitOne(5000) > $null + $wait_async.AsyncWaitHandle.WaitOne($np_timeout) > $null if (-not $wait_async.IsCompleted) { - throw "timeout while waiting for child process to connect to named pipe" + $msg = "Ansible encountered a timeout while waiting for the async task to start and connect to the named" + $msg += "pipe. This can be affected by the performance of the target - you can increase this timeout using" + $msg += "WIN_ASYNC_STARTUP_TIMEOUT or just for this host using the win_async_startup_timeout hostvar if " + $msg += "this keeps happening." + throw $msg } $pipe.EndWaitForConnection($wait_async) diff --git a/lib/ansible/executor/powershell/module_manifest.py b/lib/ansible/executor/powershell/module_manifest.py index 4cea859631d..aa746d4755b 100644 --- a/lib/ansible/executor/powershell/module_manifest.py +++ b/lib/ansible/executor/powershell/module_manifest.py @@ -294,6 +294,7 @@ def _create_powershell_wrapper(b_module_data, module_path, module_args, exec_manifest["actions"].insert(0, 'async_wrapper') exec_manifest["async_jid"] = str(random.randint(0, 999999999999)) exec_manifest["async_timeout_sec"] = async_timeout + exec_manifest["async_startup_timeout"] = C.config.get_config_value("WIN_ASYNC_STARTUP_TIMEOUT", variables=task_vars) if become and become_method == 'runas': finder.scan_exec_script('exec_wrapper')