fiber-scheduler 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/fiber_scheduler/compatibility.rb +51 -4
- data/lib/fiber_scheduler/version.rb +1 -1
- data/lib/fiber_scheduler.rb +45 -14
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d6a375b6e9a2d17be96e9c118ac624bbcbea154f961a205a9e1b0fc560b96f5e
|
|
4
|
+
data.tar.gz: 54e447b2977cfeb14bb06db5286eb3b291e2645dd9f0cc92f5aca2f5a8081372
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c5f13b97d884ae06d98cdd2cea421ea8df2294e04a4ba4bc5a508df36a35f089eafd83741b7d57a105169ba93efdb512f65590c0624b225f527a046fefd23042
|
|
7
|
+
data.tar.gz: e055549f62f5ffabf6470a6d2ec3069f3d4df7bfd02bcf43f4f6a82e094927fa09ff6604186182e5d4123a6893f04b7fe6fb2ebd3b14e8da2d06468f53d6c3ee
|
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
class FiberScheduler
|
|
2
2
|
module Compatibility
|
|
3
|
+
Close = Class.new(RuntimeError)
|
|
4
|
+
|
|
3
5
|
def fiber(*args, **opts, &block)
|
|
4
6
|
return super unless Compatibility.internal?
|
|
5
7
|
|
|
6
8
|
# This is `Fiber.schedule` call inside `FiberScheduler { ... }` block.
|
|
7
|
-
|
|
9
|
+
type = args.first
|
|
10
|
+
case type
|
|
11
|
+
when :blocking
|
|
8
12
|
Fiber.new(blocking: true) {
|
|
9
13
|
Compatibility.set_internal!
|
|
10
14
|
yield
|
|
11
15
|
}.tap(&:resume)
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
when :waiting
|
|
14
18
|
parent = Fiber.current
|
|
15
19
|
finished = false # prevents races
|
|
16
20
|
blocking = false # prevents #unblock-ing a fiber that never blocked
|
|
17
21
|
|
|
18
22
|
# Don't pass *args and **opts to an unknown fiber scheduler class.
|
|
19
|
-
super() do
|
|
23
|
+
fiber = super() do
|
|
20
24
|
Compatibility.set_internal!
|
|
21
25
|
yield
|
|
22
26
|
ensure
|
|
@@ -29,15 +33,58 @@ class FiberScheduler
|
|
|
29
33
|
block(nil, nil)
|
|
30
34
|
end
|
|
31
35
|
|
|
32
|
-
|
|
36
|
+
fiber
|
|
37
|
+
|
|
38
|
+
when :fleeting
|
|
39
|
+
# Transfer to current fiber some time after a fleeting fiber yields.
|
|
40
|
+
unblock(nil, Fiber.current)
|
|
41
|
+
# Alternative to #unblock: Fiber.scheduler.push(Fiber.current)
|
|
42
|
+
|
|
43
|
+
fiber = Fiber.new(blocking: false) do
|
|
44
|
+
Compatibility.set_internal!
|
|
45
|
+
yield
|
|
46
|
+
rescue Close
|
|
47
|
+
# Fiber scheduler is closing.
|
|
48
|
+
ensure
|
|
49
|
+
_fleeting.delete(Fiber.current)
|
|
50
|
+
end
|
|
51
|
+
_fleeting[fiber] = nil
|
|
52
|
+
fiber.tap(&:transfer)
|
|
53
|
+
|
|
54
|
+
when nil
|
|
33
55
|
# Don't pass *args and **opts to an unknown fiber scheduler class.
|
|
34
56
|
super() do
|
|
35
57
|
Compatibility.set_internal!
|
|
36
58
|
yield
|
|
37
59
|
end
|
|
60
|
+
|
|
61
|
+
else
|
|
62
|
+
raise "Unknown type"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# #close and #_fleeting handle a complexity in Async::Scheduler#close, more
|
|
67
|
+
# specifically this line:
|
|
68
|
+
# https://github.com/socketry/async/blob/456df488d801572821eaf5ec2fda10e3b9744a5f/lib/async/scheduler.rb#L55
|
|
69
|
+
def close
|
|
70
|
+
super
|
|
71
|
+
rescue
|
|
72
|
+
if _fleeting.empty?
|
|
73
|
+
Kernel.raise
|
|
74
|
+
else
|
|
75
|
+
# #dup is used because #_fleeting is modified during iteration.
|
|
76
|
+
_fleeting.dup.each do |fiber, _|
|
|
77
|
+
fiber.raise(Close)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
super # retry
|
|
38
81
|
end
|
|
39
82
|
end
|
|
40
83
|
|
|
84
|
+
def _fleeting
|
|
85
|
+
@_fleeting ||= {}
|
|
86
|
+
end
|
|
87
|
+
|
|
41
88
|
def self.set_internal!
|
|
42
89
|
Thread.current[:_fiber_scheduler] = true # Sets a FIBER local var!
|
|
43
90
|
end
|
data/lib/fiber_scheduler.rb
CHANGED
|
@@ -10,14 +10,12 @@ rescue LoadError
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
module Kernel
|
|
13
|
-
def FiberScheduler(
|
|
13
|
+
def FiberScheduler(type = nil, &block)
|
|
14
14
|
if Fiber.scheduler.nil?
|
|
15
|
-
|
|
16
|
-
Fiber.set_scheduler(scheduler)
|
|
15
|
+
Fiber.set_scheduler(FiberScheduler.new)
|
|
17
16
|
|
|
18
17
|
begin
|
|
19
18
|
yield
|
|
20
|
-
scheduler.close
|
|
21
19
|
ensure
|
|
22
20
|
Fiber.set_scheduler(nil)
|
|
23
21
|
end
|
|
@@ -28,26 +26,27 @@ module Kernel
|
|
|
28
26
|
if scheduler.is_a?(FiberScheduler)
|
|
29
27
|
# The default waiting is 'true' as that is the most intuitive behavior
|
|
30
28
|
# for a nested FiberScheduler call.
|
|
31
|
-
Fiber.schedule(
|
|
29
|
+
Fiber.schedule(type, &block)
|
|
32
30
|
|
|
33
31
|
# Unknown fiber scheduler class; can't just pass options to
|
|
34
32
|
# Fiber.schedule, handle each option separately.
|
|
35
33
|
else
|
|
36
34
|
scheduler.singleton_class.prepend(FiberScheduler::Compatibility)
|
|
37
35
|
|
|
38
|
-
|
|
36
|
+
case type
|
|
37
|
+
when :blocking
|
|
39
38
|
fiber = Fiber.new(blocking: true) do
|
|
40
39
|
FiberScheduler::Compatibility.set_internal!
|
|
41
40
|
yield
|
|
42
41
|
end
|
|
43
42
|
fiber.tap(&:resume)
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
when :waiting
|
|
46
45
|
parent = Fiber.current
|
|
47
46
|
finished = false # prevents races
|
|
48
47
|
blocking = false # prevents #unblock-ing a fiber that never blocked
|
|
49
48
|
|
|
50
|
-
Fiber.schedule do
|
|
49
|
+
fiber = Fiber.schedule do
|
|
51
50
|
FiberScheduler::Compatibility.set_internal!
|
|
52
51
|
yield
|
|
53
52
|
ensure
|
|
@@ -67,11 +66,30 @@ module Kernel
|
|
|
67
66
|
scheduler.block(nil, nil)
|
|
68
67
|
end
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
fiber
|
|
70
|
+
|
|
71
|
+
when :fleeting
|
|
72
|
+
scheduler.unblock(nil, Fiber.current)
|
|
73
|
+
|
|
74
|
+
fiber = Fiber.new(blocking: false) do
|
|
75
|
+
FiberScheduler::Compatibility.set_internal!
|
|
76
|
+
yield
|
|
77
|
+
rescue FiberScheduler::Compatibility::Close
|
|
78
|
+
# Fiber scheduler is closing.
|
|
79
|
+
ensure
|
|
80
|
+
scheduler._fleeting.delete(Fiber.current)
|
|
81
|
+
end
|
|
82
|
+
scheduler._fleeting[fiber] = nil
|
|
83
|
+
fiber.tap(&:transfer)
|
|
84
|
+
|
|
85
|
+
when nil
|
|
71
86
|
Fiber.schedule do
|
|
72
87
|
FiberScheduler::Compatibility.set_internal!
|
|
73
88
|
yield
|
|
74
89
|
end
|
|
90
|
+
|
|
91
|
+
else
|
|
92
|
+
raise "Unknown type"
|
|
75
93
|
end
|
|
76
94
|
end
|
|
77
95
|
end
|
|
@@ -170,13 +188,14 @@ class FiberScheduler
|
|
|
170
188
|
@timeouts.timeout(duration, exception, message, &block)
|
|
171
189
|
end
|
|
172
190
|
|
|
173
|
-
def fiber(
|
|
191
|
+
def fiber(type = nil, &block)
|
|
174
192
|
current = Fiber.current
|
|
175
193
|
|
|
176
|
-
|
|
177
|
-
|
|
194
|
+
case type
|
|
195
|
+
when :blocking
|
|
178
196
|
Fiber.new(blocking: true, &block).tap(&:resume)
|
|
179
|
-
|
|
197
|
+
|
|
198
|
+
when :waiting
|
|
180
199
|
finished = false # prevents races
|
|
181
200
|
fiber = Fiber.new(blocking: false) do
|
|
182
201
|
@count += 1
|
|
@@ -201,7 +220,16 @@ class FiberScheduler
|
|
|
201
220
|
end
|
|
202
221
|
|
|
203
222
|
fiber
|
|
204
|
-
|
|
223
|
+
|
|
224
|
+
when :fleeting
|
|
225
|
+
if current != @fiber
|
|
226
|
+
# nested Fiber.schedule
|
|
227
|
+
@nested << current
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
Fiber.new(blocking: false, &block).tap(&:transfer)
|
|
231
|
+
|
|
232
|
+
when nil
|
|
205
233
|
if current != @fiber
|
|
206
234
|
# nested Fiber.schedule
|
|
207
235
|
@nested << current
|
|
@@ -214,6 +242,9 @@ class FiberScheduler
|
|
|
214
242
|
@count -= 1
|
|
215
243
|
end
|
|
216
244
|
fiber.tap(&:transfer)
|
|
245
|
+
|
|
246
|
+
else
|
|
247
|
+
raise "Unknown type"
|
|
217
248
|
end
|
|
218
249
|
end
|
|
219
250
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fiber-scheduler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bruno Sutic
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-02-
|
|
11
|
+
date: 2022-02-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: async
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0.
|
|
33
|
+
version: '0.10'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0.
|
|
40
|
+
version: '0.10'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rspec
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|