Class: Async::Limiter::Generic
- Inherits:
-
Object
- Object
- Async::Limiter::Generic
- Defined in:
- lib/async/limiter/generic.rb
Overview
Generic limiter class with unlimited concurrency by default.
This provides the foundation for rate limiting and concurrency control. Subclasses can override methods to implement specific limiting behaviors.
The Generic limiter coordinates timing strategies with concurrency control, providing thread-safe acquisition with deadline tracking and cost-based consumption.
Instance Attribute Summary collapse
- #Registry-like object for utilization metrics. ⇒ Object readonly
-
#tags ⇒ Object
readonly
Returns the value of attribute tags.
- #Tags associated with this limiter for identification or categorization.(associatedwiththislimiter) ⇒ Object readonly
-
#timing ⇒ Object
readonly
Returns the value of attribute timing.
-
#utilization ⇒ Object
readonly
Returns the value of attribute utilization.
Instance Method Summary collapse
-
#acquire(timeout: nil, cost: 1, **options) ⇒ Object
Manually acquire a resource with timing and concurrency coordination.
-
#as_json ⇒ Object
Get a JSON-compatible representation of the limiter statistics.
-
#async(parent: (@parent || Task.current), **options) ⇒ Object
Execute a task asynchronously with unlimited concurrency.
-
#initialize(timing: Timing::None, parent: nil, tags: nil, utilization: Async::Utilization::Registry.new) ⇒ Generic
constructor
Initialize a new generic limiter.
- #limited? ⇒ Boolean
-
#release(resource = true) ⇒ Object
Release a previously acquired resource.
-
#statistics ⇒ Object
Get current limiter statistics.
- #Strategy for timing constraints.= ⇒ Object
-
#sync ⇒ Object
Execute a task synchronously with unlimited concurrency.
-
#to_json ⇒ Object
Get a JSON string representation of the limiter statistics.
Constructor Details
#initialize(timing: Timing::None, parent: nil, tags: nil, utilization: Async::Utilization::Registry.new) ⇒ Generic
Initialize a new generic limiter.
29 30 31 32 33 34 35 36 |
# File 'lib/async/limiter/generic.rb', line 29 def initialize(timing: Timing::None, parent: nil, tags: nil, utilization: Async::Utilization::Registry.new) @timing = timing @parent = parent @tags = @utilization = utilization @mutex = Mutex.new end |
Instance Attribute Details
#Registry-like object for utilization metrics. ⇒ Object (readonly)
45 |
# File 'lib/async/limiter/generic.rb', line 45 attr :utilization |
#tags ⇒ Object (readonly)
Returns the value of attribute tags.
42 43 44 |
# File 'lib/async/limiter/generic.rb', line 42 def @tags end |
#Tags associated with this limiter for identification or categorization.(associatedwiththislimiter) ⇒ Object (readonly)
42 |
# File 'lib/async/limiter/generic.rb', line 42 attr :tags |
#timing ⇒ Object (readonly)
Returns the value of attribute timing.
39 40 41 |
# File 'lib/async/limiter/generic.rb', line 39 def timing @timing end |
#utilization ⇒ Object (readonly)
Returns the value of attribute utilization.
45 46 47 |
# File 'lib/async/limiter/generic.rb', line 45 def utilization @utilization end |
Instance Method Details
#acquire(timeout: nil, cost: 1, **options) ⇒ Object
Manually acquire a resource with timing and concurrency coordination.
This method provides the core acquisition logic with support for:
-
Flexible timeout handling (blocking, non-blocking, timed)
-
Cost-based consumption for timing strategies
-
Deadline tracking to prevent timeout violations
-
Automatic resource cleanup with block usage
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/async/limiter/generic.rb', line 95 def acquire(timeout: nil, cost: 1, **) # Validate cost against timing strategy capacity: maximum_cost = @timing.maximum_cost if cost > maximum_cost raise ArgumentError, "Cost #{cost} exceeds maximum supported cost #{maximum_cost} for timing strategy!" end resource = nil deadline = Deadline.start(timeout) # Atomically handle timing constraints and concurrency logic: acquire_synchronized(timeout, cost, **) do # Wait for timing constraints to be satisfied (mutex released during sleep) return nil unless @timing.wait(@mutex, deadline, cost) # Execute the concurrency-specific acquisition logic resource = acquire_resource(deadline, **) # Record timing acquisition if successful if resource @timing.acquire(cost) else # `acquire_concurrency` should return nil if deadline reached: return nil end resource end return resource unless block_given? begin yield(resource) ensure release(resource) end end |
#as_json ⇒ Object
Get a JSON-compatible representation of the limiter statistics.
150 151 152 |
# File 'lib/async/limiter/generic.rb', line 150 def as_json(...) statistics end |
#async(parent: (@parent || Task.current), **options) ⇒ Object
Execute a task asynchronously with unlimited concurrency.
59 60 61 62 63 64 65 66 |
# File 'lib/async/limiter/generic.rb', line 59 def async(parent: (@parent || Task.current), **) acquire parent.async(**) do |task| yield task ensure release end end |
#limited? ⇒ Boolean
48 49 50 |
# File 'lib/async/limiter/generic.rb', line 48 def limited? false end |
#release(resource = true) ⇒ Object
Release a previously acquired resource.
134 135 136 |
# File 'lib/async/limiter/generic.rb', line 134 def release(resource = true) release_resource(resource) end |
#statistics ⇒ Object
Get current limiter statistics.
140 141 142 143 144 145 146 |
# File 'lib/async/limiter/generic.rb', line 140 def statistics @mutex.synchronize do { timing: @timing.statistics } end end |
#Strategy for timing constraints.= ⇒ Object
39 |
# File 'lib/async/limiter/generic.rb', line 39 attr :timing |
#sync ⇒ Object
Execute a task synchronously with unlimited concurrency.
72 73 74 75 76 |
# File 'lib/async/limiter/generic.rb', line 72 def sync acquire do yield(Task.current) end end |
#to_json ⇒ Object
Get a JSON string representation of the limiter statistics.
156 157 158 |
# File 'lib/async/limiter/generic.rb', line 156 def to_json(...) as_json.to_json(...) end |