@@ -246,13 +246,19 @@ def execute_command(cmd:, error_message:, logger:)
246246 begin
247247 if logger
248248 logger . info ( "Running: #{ cmd } " )
249- stdout_and_stderr_str , status = Open3 . capture2e ( cmd )
250- logger . info ( stdout_and_stderr_str )
249+
250+ # Use the safer non-blocking approach instead of capture2e
251+ stdout_str , stderr_str , status = safe_capture2e ( cmd )
252+
253+ # Log both stdout and stderr
254+ logger . info ( stdout_str + stderr_str )
255+
251256 result = status . success?
252257 logger . error ( error_message ) unless result
253258 result
254259 else
255- stdout_and_stderr_str , status = Open3 . capture2e ( cmd )
260+ # Use the safer approach without logging
261+ _ , _ , status = safe_capture2e ( cmd )
256262 status . success?
257263 end
258264 rescue => e
@@ -263,6 +269,41 @@ def execute_command(cmd:, error_message:, logger:)
263269 false
264270 end
265271 end
272+
273+ # A safer replacement for Open3.capture2e that avoids deadlocks
274+ # when used within Ruby Ractors
275+ #
276+ # @param cmd [String] Command to execute
277+ # @return [Array<String, String, Process::Status>] stdout, stderr, and status
278+ def safe_capture2e ( cmd )
279+ Open3 . popen3 ( cmd ) do |i , o , e , t |
280+ i . close
281+ readables = [ o , e ]
282+ stdout = [ ]
283+ stderr = [ ]
284+
285+ until readables . empty?
286+ readable , = IO . select ( readables )
287+
288+ if readable &.include? ( o )
289+ chunk = o . read_nonblock ( 4096 , exception : false )
290+ stdout << chunk if chunk && chunk != :wait_readable
291+ readables . delete ( o ) if chunk . nil?
292+ end
293+
294+ if readable &.include? ( e )
295+ chunk = e . read_nonblock ( 4096 , exception : false )
296+ stderr << chunk if chunk && chunk != :wait_readable
297+ readables . delete ( e ) if chunk . nil?
298+ end
299+
300+ # Remove streams that have reached EOF
301+ readables . reject! ( &:eof? ) if readables . any?
302+ end
303+
304+ [ stdout . join , stderr . join , t . value ]
305+ end
306+ end
266307 end
267308 end
268309end
0 commit comments