Module: Aidp::Concurrency::Wait
- Defined in:
- lib/aidp/concurrency/wait.rb
Overview
Deterministic condition waiting with timeouts and intervals.
Replaces sleep-based polling loops with proper timeout enforcement and early exit on condition satisfaction.
Class Method Summary collapse
-
.for_file(path, timeout: nil, interval: nil) ⇒ String
Wait for a file to exist.
-
.for_port(host, port, timeout: nil, interval: nil) ⇒ Boolean
Wait for a TCP port to be open.
-
.for_process_exit(pid, timeout: nil, interval: nil) ⇒ Process::Status
Wait for a process to exit.
-
.until(timeout: nil, interval: nil, message: nil) { ... } ⇒ Object
Wait until a condition becomes true, with timeout and interval polling.
Class Method Details
.for_file(path, timeout: nil, interval: nil) ⇒ String
Wait for a file to exist.
76 77 78 79 80 81 82 83 |
# File 'lib/aidp/concurrency/wait.rb', line 76 def for_file(path, timeout: nil, interval: nil) self.until( timeout: timeout, interval: interval, message: "File not found: #{path} (waited #{timeout || Concurrency.configuration.default_timeout}s)" ) { File.exist?(path) } path end |
.for_port(host, port, timeout: nil, interval: nil) ⇒ Boolean
Wait for a TCP port to be open.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/aidp/concurrency/wait.rb', line 93 def for_port(host, port, timeout: nil, interval: nil) require "socket" self.until( timeout: timeout, interval: interval, message: "Port #{host}:#{port} not open (waited #{timeout || Concurrency.configuration.default_timeout}s)" ) do socket = TCPSocket.new(host, port) socket.close true rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ETIMEDOUT false end end |
.for_process_exit(pid, timeout: nil, interval: nil) ⇒ Process::Status
Wait for a process to exit.
115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/aidp/concurrency/wait.rb', line 115 def for_process_exit(pid, timeout: nil, interval: nil) status = nil self.until( timeout: timeout, interval: interval, message: "Process #{pid} did not exit (waited #{timeout || Concurrency.configuration.default_timeout}s)" ) do _, status = Process.waitpid2(pid, Process::WNOHANG) status # Returns truthy when process has exited end status end |
.until(timeout: nil, interval: nil, message: nil) { ... } ⇒ Object
Wait until a condition becomes true, with timeout and interval polling.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/aidp/concurrency/wait.rb', line 37 def until(timeout: nil, interval: nil, message: nil, &block) timeout ||= Concurrency.configuration.default_timeout interval ||= Concurrency.configuration.default_interval ||= "Condition not met within #{timeout}s" raise ArgumentError, "Block required" unless block_given? start_time = monotonic_time deadline = start_time + timeout elapsed = 0.0 loop do result = block.call if result log_wait_completion(elapsed) if should_log_wait?(elapsed) return result end elapsed = monotonic_time - start_time remaining = deadline - monotonic_time if remaining <= 0 log_timeout(elapsed, ) raise Concurrency::TimeoutError, end # Sleep for interval or remaining time, whichever is shorter sleep_duration = [interval, remaining].min sleep(sleep_duration) if sleep_duration > 0 end end |