Class: DiscordRDA::ExecutionSupervisor
- Inherits:
-
Object
- Object
- DiscordRDA::ExecutionSupervisor
- Defined in:
- lib/discord_rda/core/execution_supervisor.rb
Defined Under Namespace
Classes: CircuitOpenError, ConcurrencyLimitError, IsolatedExecutionError, TimeoutError
Constant Summary collapse
- DEFAULT_POLICY =
{ timeout_seconds: 15, max_concurrency: 8, failure_threshold: 5, cooldown_seconds: 60 }.freeze
Instance Attribute Summary collapse
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
Instance Method Summary collapse
- #execute(key, policy: {}, &block) ⇒ Object
-
#initialize(logger: nil) ⇒ ExecutionSupervisor
constructor
A new instance of ExecutionSupervisor.
- #run_isolated(ruby_code:, timeout_seconds: 15, memory_limit_mb: nil, env: {}) ⇒ Object
Constructor Details
#initialize(logger: nil) ⇒ ExecutionSupervisor
Returns a new instance of ExecutionSupervisor.
24 25 26 27 28 |
# File 'lib/discord_rda/core/execution_supervisor.rb', line 24 def initialize(logger: nil) @logger = logger @states = {} @mutex = Mutex.new end |
Instance Attribute Details
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
22 23 24 |
# File 'lib/discord_rda/core/execution_supervisor.rb', line 22 def logger @logger end |
Instance Method Details
#execute(key, policy: {}, &block) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/discord_rda/core/execution_supervisor.rb', line 30 def execute(key, policy: {}, &block) merged = DEFAULT_POLICY.merge(policy || {}) state = state_for(key) raise CircuitOpenError, "Circuit open for #{key}" if circuit_open?(state) acquire_slot!(key, state, merged) begin result = ::Timeout.timeout(merged[:timeout_seconds]) { block.call } record_success(state) result rescue ::Timeout::Error => e record_failure(state) raise TimeoutError, e. rescue StandardError record_failure(state) raise ensure release_slot(state) end end |
#run_isolated(ruby_code:, timeout_seconds: 15, memory_limit_mb: nil, env: {}) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/discord_rda/core/execution_supervisor.rb', line 52 def run_isolated(ruby_code:, timeout_seconds: 15, memory_limit_mb: nil, env: {}) Tempfile.create(['discord_rda_isolated', '.rb']) do |file| file.write(build_isolated_runner(ruby_code, memory_limit_mb)) file.flush stdout, stderr, status = spawn_with_timeout( [RbConfig.ruby, file.path], timeout_seconds: timeout_seconds, env: env ) raise IsolatedExecutionError, stderr unless status.success? stdout end end |