Class: RailsAiBridge::Introspector::ParallelRunner
- Inherits:
-
Object
- Object
- RailsAiBridge::Introspector::ParallelRunner
- Defined in:
- lib/rails_ai_bridge/introspector/parallel_runner.rb
Overview
Runs multiple introspectors concurrently using a fixed thread pool.
Requires concurrent-ruby (already a transitive dependency of Rails).
Falls back gracefully when the gem is unavailable — callers should
check ParallelRunner.available? before using this runner.
Pool size and per-future timeout are driven by
Configuration (+parallel_pool_size+ and
parallel_timeout_seconds), so hosts can tune concurrency without
touching this class.
Each introspector is executed in its own future. Errors — including
per-future timeouts — are captured per-introspector and returned as
{ error: message } hashes, matching the convention used throughout
#call.
Class Method Summary collapse
-
.available? ⇒ Boolean
Returns
truewhen parallel execution is safe to use. -
.call(introspectors, app) ⇒ Hash{Symbol => Object}
Runs
introspectorsconcurrently and returns a Hash of results.
Class Method Details
.available? ⇒ Boolean
Returns true when parallel execution is safe to use.
Parallel execution is considered unsafe when:
concurrent-rubyis not loaded (+Concurrent::Future+ is undefined)- ActiveRecord's connection pool has only one slot (common in transactional tests or SQLite single-connection setups)
63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/rails_ai_bridge/introspector/parallel_runner.rb', line 63 def available? return false unless defined?(Concurrent::Future) == 'constant' if defined?(ActiveRecord::Base) pool_size = begin ActiveRecord::Base.connection_pool.size rescue StandardError nil end return false if pool_size && pool_size <= 1 end true end |
.call(introspectors, app) ⇒ Hash{Symbol => Object}
Runs introspectors concurrently and returns a Hash of results.
The number of threads is min(introspectors.size, parallel_pool_size).
Each future is given parallel_timeout_seconds to complete; if it
exceeds the timeout the result is { error: "timed out after Ns" }.
The thread pool is always shut down in an ensure block, even if
an unexpected exception escapes.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/rails_ai_bridge/introspector/parallel_runner.rb', line 39 def call(introspectors, app) return {} if introspectors.empty? cfg = RailsAiBridge.configuration size = [introspectors.size, cfg.parallel_pool_size].min timeout = cfg.parallel_timeout_seconds pool = Concurrent::FixedThreadPool.new(size) futures = schedule_futures(introspectors, app, pool) collect_results(futures, timeout) ensure if pool pool.shutdown pool.kill unless pool.wait_for_termination(timeout || 10) end end |