Class: Woods::Operator::PipelineGuard
- Inherits:
-
Object
- Object
- Woods::Operator::PipelineGuard
- Defined in:
- lib/woods/operator/pipeline_guard.rb
Overview
Rate limiter for pipeline operations using file-based state.
Enforces a cooldown between consecutive runs of the same operation to prevent accidental repeated extraction or embedding.
Instance Method Summary collapse
-
#allow?(operation) ⇒ Boolean
Check if an operation is allowed (cooldown elapsed).
-
#initialize(state_dir:, cooldown: 300) ⇒ PipelineGuard
constructor
A new instance of PipelineGuard.
-
#last_run(operation) ⇒ Time?
Get the last run time for an operation.
-
#record!(operation) ⇒ void
Record that an operation has just run.
Constructor Details
#initialize(state_dir:, cooldown: 300) ⇒ PipelineGuard
Returns a new instance of PipelineGuard.
24 25 26 27 28 |
# File 'lib/woods/operator/pipeline_guard.rb', line 24 def initialize(state_dir:, cooldown: 300) @state_dir = state_dir @cooldown = cooldown @state_path = File.join(state_dir, 'pipeline_guard.json') end |
Instance Method Details
#allow?(operation) ⇒ Boolean
Check if an operation is allowed (cooldown elapsed).
34 35 36 37 38 39 |
# File 'lib/woods/operator/pipeline_guard.rb', line 34 def allow?(operation) last = last_run(operation) return true if last.nil? (Time.now - last) >= @cooldown end |
#last_run(operation) ⇒ Time?
Get the last run time for an operation.
70 71 72 73 74 75 76 77 78 |
# File 'lib/woods/operator/pipeline_guard.rb', line 70 def last_run(operation) state = read_state = state[operation.to_s] return nil if .nil? Time.parse() rescue ArgumentError nil end |
#record!(operation) ⇒ void
This method returns an undefined value.
Record that an operation has just run.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/woods/operator/pipeline_guard.rb', line 45 def record!(operation) FileUtils.mkdir_p(@state_dir) File.open(@state_path, File::RDWR | File::CREAT) do |f| f.flock(File::LOCK_EX) content = f.read state = if content.empty? {} else begin JSON.parse(content) rescue StandardError {} end end state[operation.to_s] = Time.now.iso8601 f.rewind f.write(JSON.generate(state)) f.truncate(f.pos) end end |