Class: Lutaml::Hal::SingleFlight
- Inherits:
-
Object
- Object
- Lutaml::Hal::SingleFlight
- Defined in:
- lib/lutaml/hal/single_flight.rb
Overview
Coalesces concurrent calls that share a key so the work runs once and the result (or error) is shared by all callers. Calls for different keys run in parallel — only same-key callers wait on the in-flight leader.
Pure stdlib (Mutex + ConditionVariable); no external dependency. In-flight entries are removed once resolved, so memory is bounded by concurrency, not by the number of distinct keys ever seen.
Defined Under Namespace
Classes: Call
Instance Method Summary collapse
-
#initialize ⇒ SingleFlight
constructor
A new instance of SingleFlight.
-
#run(key) ⇒ Object
Run the block at most once per key under concurrency, returning its result.
Constructor Details
#initialize ⇒ SingleFlight
Returns a new instance of SingleFlight.
15 16 17 18 |
# File 'lib/lutaml/hal/single_flight.rb', line 15 def initialize @registry_mutex = Mutex.new @calls = {} end |
Instance Method Details
#run(key) ⇒ Object
Run the block at most once per key under concurrency, returning its result. The first caller for a key (the leader) runs the block; others wait and receive the same value (or re-raise the same error).
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/lutaml/hal/single_flight.rb', line 23 def run(key) leader = false call = @registry_mutex.synchronize do @calls[key] ||= begin leader = true Call.new(Mutex.new, ConditionVariable.new, false) end end return await(call) unless leader begin call.value = yield rescue StandardError => e call.error = e ensure @registry_mutex.synchronize { @calls.delete(key) } call.mutex.synchronize do call.done = true call.cond.broadcast end end raise call.error if call.error call.value end |