Class: Async::Limiter::Generic

Inherits:
Object
  • Object
show all
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.

Direct Known Subclasses

Limited, Queued

Instance Attribute Summary collapse

Instance Method Summary collapse

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 = 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

#tagsObject (readonly)

Returns the value of attribute tags.



42
43
44
# File 'lib/async/limiter/generic.rb', line 42

def tags
  @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

#timingObject (readonly)

Returns the value of attribute timing.



39
40
41
# File 'lib/async/limiter/generic.rb', line 39

def timing
  @timing
end

#utilizationObject (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, **options)
	# 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, **options) 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, **options)
		
		# 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_jsonObject

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), **options)
	acquire
	parent.async(**options) do |task|
		yield task
	ensure
		release
	end
end

#limited?Boolean

Returns:

  • (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

#statisticsObject

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

#syncObject

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_jsonObject

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