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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f7bcca0b0eba6eebe85dd32baa0ffd67059bcdb0623416b818182bf779e38809
4
- data.tar.gz: 061a086ae31c238f1d2c3d17598400f3efc01a500de746105255f7582b90251c
3
+ metadata.gz: 0601ed7bbe9065d035b7d9e0ff81931f8f37d0f71618c73584568db08f33df74
4
+ data.tar.gz: d18230e37d7fb392e5e63e80a59c4bee9e199d14141998066a4ab41bce362dab
5
5
  SHA512:
6
- metadata.gz: 455f569e561177f4f2e11e5f5713c6e04c5b30b54b01e860bca5e84770095b7f80c0d05d6afa7865773fbfb58c4170103a905ce9c3517c08fb9eec32f5a191a9
7
- data.tar.gz: b142a77817fcf868fa68f117d68fe05cf3d0ce34329855a2ef19be198924604b366deaa0ac0ec7bcaa151eaf244bb1e521908515aca44b5be1d82f794288f313
6
+ metadata.gz: 6389e3177b10524b00f25f486221cc8e400677d7d7600411002793ac2d84bd1a3f21a694867551907bfd4710189b61833e66165a1e712e6546a9f96d3aca9a67
7
+ data.tar.gz: c756a3d1b2c30c010cd314b57b640a0e211a7c0227da2fc9054420ffec8c03cfdd567b8dc3841e4ca644af4adf92a8b9959114266113553e5b56a6c426affbdd
@@ -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
@@ -21,5 +21,5 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  module Async
24
- VERSION = "1.30.3"
24
+ VERSION = "1.32.0"
25
25
  end
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.30.3
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: 2022-06-15 00:00:00.000000000 Z
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.7
183
+ rubygems_version: 3.5.3
184
184
  signing_key:
185
185
  specification_version: 4
186
186
  summary: A concurrency framework for Ruby.