async 1.30.3 → 1.32.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/async/semaphore.rb +19 -0
- data/lib/async/task.rb +44 -0
- data/lib/async/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0601ed7bbe9065d035b7d9e0ff81931f8f37d0f71618c73584568db08f33df74
|
4
|
+
data.tar.gz: d18230e37d7fb392e5e63e80a59c4bee9e199d14141998066a4ab41bce362dab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6389e3177b10524b00f25f486221cc8e400677d7d7600411002793ac2d84bd1a3f21a694867551907bfd4710189b61833e66165a1e712e6546a9f96d3aca9a67
|
7
|
+
data.tar.gz: c756a3d1b2c30c010cd314b57b640a0e211a7c0227da2fc9054420ffec8c03cfdd567b8dc3841e4ca644af4adf92a8b9959114266113553e5b56a6c426affbdd
|
data/lib/async/semaphore.rb
CHANGED
@@ -40,6 +40,25 @@ module Async
|
|
40
40
|
# The tasks waiting on this semaphore.
|
41
41
|
attr :waiting
|
42
42
|
|
43
|
+
# Allow setting the limit. This is useful for cases where the semaphore is used to limit the number of concurrent tasks, but the number of tasks is not known in advance or needs to be modified.
|
44
|
+
#
|
45
|
+
# On increasing the limit, some tasks may be immediately resumed. On decreasing the limit, some tasks may execute until the count is < than the limit.
|
46
|
+
#
|
47
|
+
# @parameter limit [Integer] The new limit.
|
48
|
+
def limit= limit
|
49
|
+
difference = limit - @limit
|
50
|
+
@limit = limit
|
51
|
+
|
52
|
+
# We can't suspend
|
53
|
+
if difference > 0
|
54
|
+
difference.times do
|
55
|
+
break unless fiber = @waiting.shift
|
56
|
+
|
57
|
+
fiber.resume
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
43
62
|
# Is the semaphore currently acquired?
|
44
63
|
def empty?
|
45
64
|
@count.zero?
|
data/lib/async/task.rb
CHANGED
@@ -84,6 +84,8 @@ module Async
|
|
84
84
|
@logger = logger || @parent.logger
|
85
85
|
|
86
86
|
@fiber = make_fiber(&block)
|
87
|
+
|
88
|
+
@defer_stop = nil
|
87
89
|
end
|
88
90
|
|
89
91
|
attr :logger
|
@@ -162,6 +164,13 @@ module Async
|
|
162
164
|
return
|
163
165
|
end
|
164
166
|
|
167
|
+
# If we are deferring stop...
|
168
|
+
if @defer_stop == false
|
169
|
+
# Don't stop now... but update the state so we know we need to stop later.
|
170
|
+
@defer_stop = true
|
171
|
+
return false
|
172
|
+
end
|
173
|
+
|
165
174
|
if self.running?
|
166
175
|
if self.current?
|
167
176
|
if later
|
@@ -182,6 +191,41 @@ module Async
|
|
182
191
|
end
|
183
192
|
end
|
184
193
|
|
194
|
+
# Defer the handling of stop. During the execution of the given block, if a stop is requested, it will be deferred until the block exits. This is useful for ensuring graceful shutdown of servers and other long-running tasks. You should wrap the response handling code in a defer_stop block to ensure that the task is stopped when the response is complete but not before.
|
195
|
+
#
|
196
|
+
# You can nest calls to defer_stop, but the stop will only be deferred until the outermost block exits.
|
197
|
+
#
|
198
|
+
# If stop is invoked a second time, it will be immediately executed.
|
199
|
+
#
|
200
|
+
# @yields {} The block of code to execute.
|
201
|
+
def defer_stop
|
202
|
+
# Tri-state variable for controlling stop:
|
203
|
+
# - nil: defer_stop has not been called.
|
204
|
+
# - false: defer_stop has been called and we are not stopping.
|
205
|
+
# - true: defer_stop has been called and we will stop when exiting the block.
|
206
|
+
if @defer_stop.nil?
|
207
|
+
# If we are not deferring stop already, we can defer it now:
|
208
|
+
@defer_stop = false
|
209
|
+
|
210
|
+
begin
|
211
|
+
yield
|
212
|
+
rescue Stop
|
213
|
+
# If we are exiting due to a stop, we shouldn't try to invoke stop again:
|
214
|
+
@defer_stop = nil
|
215
|
+
raise
|
216
|
+
ensure
|
217
|
+
# If we were asked to stop, we should do so now:
|
218
|
+
if @defer_stop
|
219
|
+
@defer_stop = nil
|
220
|
+
self.stop
|
221
|
+
end
|
222
|
+
end
|
223
|
+
else
|
224
|
+
# If we are deferring stop already, entering it again is a no-op.
|
225
|
+
yield
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
185
229
|
# Lookup the {Task} for the current fiber. Raise `RuntimeError` if none is available.
|
186
230
|
# @return [Async::Task]
|
187
231
|
# @raise [RuntimeError] if task was not {set!} for the current fiber.
|
data/lib/async/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.32.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: console
|
@@ -180,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
180
180
|
- !ruby/object:Gem::Version
|
181
181
|
version: '0'
|
182
182
|
requirements: []
|
183
|
-
rubygems_version: 3.3
|
183
|
+
rubygems_version: 3.5.3
|
184
184
|
signing_key:
|
185
185
|
specification_version: 4
|
186
186
|
summary: A concurrency framework for Ruby.
|