From 13a7290819bec684ee1b7e5fa3bfe634e04fefa3 Mon Sep 17 00:00:00 2001 From: dcrosby Date: Tue, 18 Jun 2024 13:20:20 -0700 Subject: [PATCH] [Shellout::Unix] Progressive select timeout [#245] This intends to strike a balance between quick and longer-running shellouts Signed-off-by: David Crosby --- .rubocop.yml | 4 ++-- lib/mixlib/shellout/unix.rb | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 1fa58bfa..b988e3bd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,5 @@ AllCops: - TargetRubyVersion: 2.4 + TargetRubyVersion: 2.5 Lint/UnderscorePrefixedVariableName: Exclude: @@ -8,4 +8,4 @@ Lint/UnderscorePrefixedVariableName: # Configuration parameters: ContextCreatingMethods. Lint/UselessAccessModifier: Exclude: - - 'lib/mixlib/shellout/windows/core_ext.rb' \ No newline at end of file + - 'lib/mixlib/shellout/windows/core_ext.rb' diff --git a/lib/mixlib/shellout/unix.rb b/lib/mixlib/shellout/unix.rb index e3d09929..1ab50e42 100644 --- a/lib/mixlib/shellout/unix.rb +++ b/lib/mixlib/shellout/unix.rb @@ -104,10 +104,15 @@ def run_command write_to_child_stdin + select_timeout = 0.001 # 1 millisecond + until @status - ready_buffers = attempt_buffer_read + ready_buffers = attempt_buffer_read(select_timeout) unless ready_buffers - @execution_time += READ_WAIT_TIME + @execution_time += select_timeout + + # 1.3 multiplier is so we get ~10 selects before we hit the 0.01 threshold + select_timeout *= 1.3 unless select_timeout > READ_WAIT_TIME if @execution_time >= timeout && !@result # kill the bad proccess reap_errant_child @@ -265,8 +270,8 @@ def write_to_child_stdin child_stdin.close # Kick things off end - def attempt_buffer_read - ready = IO.select(open_pipes, nil, nil, READ_WAIT_TIME) + def attempt_buffer_read(select_timeout = READ_WAIT_TIME) + ready = IO.select(open_pipes, nil, nil, select_timeout) if ready read_stdout_to_buffer if ready.first.include?(child_stdout) read_stderr_to_buffer if ready.first.include?(child_stderr)