From 4005f73eda0c11f24103da933f8ba1a59554cc1c Mon Sep 17 00:00:00 2001 From: Sean Millichamp Date: Wed, 26 Jun 2024 12:47:02 -0400 Subject: [PATCH] Ensure bash shell executions close file descriptors Currently Bolt::Shell::Bash will leaves open file descriptors at the conclusion of execute(). The file descriptions do fall out of scope at the conclusion of the execute() method and the Ruby GC eventually closes them. However, on a very busy Bolt invocation with lots of short-lived Tasks or a number of Tasks running in parallel (e.g. via background()) the number of open FDs before garbage collection can get moderately high, hitting problems on systems with low file descriptor limits. !bug * **Explicitly close Bolt::Shell::Bash file descriptors** Ensure file descriptors in Bolt::Shell::Bash are explicitly closed, helping to alleviate the chance of hitting file descriptor limits on systems with low defaults (e.g. Mac OS). --- lib/bolt/shell/bash.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/bolt/shell/bash.rb b/lib/bolt/shell/bash.rb index 6317145708..5c533b0b95 100644 --- a/lib/bolt/shell/bash.rb +++ b/lib/bolt/shell/bash.rb @@ -470,7 +470,10 @@ def execute(command, sudoable: false, **options) result_output.merged_output << to_print } rescue Errno::EAGAIN, EOFError + ensure + stream.close end + inp.close result_output.stdout << read_streams[out] result_output.stderr << read_streams[err] result_output.exit_code = t.value.respond_to?(:exitstatus) ? t.value.exitstatus : t.value @@ -490,7 +493,7 @@ def execute(command, sudoable: false, **options) result_output rescue StandardError # Ensure we close stdin and kill the child process - inp&.close + inp.close unless inp.nil? || inp.closed? t&.terminate if t&.alive? @logger.trace { "Command aborted" } raise