fiber_scheduler 0.11.0 → 0.12.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: 53d696318655c53901ad5236d6a2beb1ae14b915ce2f2c64f05ef1e3e40988a9
4
- data.tar.gz: be844ddb1fb5010732ec84a01b5ef73256e60abe91e126d461daf4bbe5467012
3
+ metadata.gz: e6bff2da15e7d0b5295c4e97e86c55377ce126173aeeb8ef81cade98f2a3bd1b
4
+ data.tar.gz: aac48ee81381541a770722eb369c7d8f90415caba4f796e7c830b35cb53fd10b
5
5
  SHA512:
6
- metadata.gz: e54d5897ea73e5a0dc8d753091c6700b3605458df9e101b90bff77b63e141054db8142720279d3556d9d5a02347b049ec83213462224e93f03055fac0a4af65c
7
- data.tar.gz: 445b10119acd9d544e69999ea32eaa567976bc73409cd1db4919a19c881ffaab76bef770192d5ec11c41989ad6e9df3d470ec6697e8e8e430d510a595959311d
6
+ metadata.gz: 5b83d8d5a5f1a7503de979bdd7f60025b9ada9d63d98166a61516c3da82ec6b1e1a385579acc5c05764cc0ac838671757e53ee980180c5bf38625bc2b7f157ea
7
+ data.tar.gz: 1c2026341f79c0d98131f04c8d51b3be410b2fef6d732e8181a2024e149f08c02bebd5a9bc8272956396dd182451395c84a36b088f811f17b7deb96eb7983830
@@ -1,5 +1,7 @@
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
 
@@ -18,7 +20,7 @@ class FiberScheduler
18
20
  blocking = false # prevents #unblock-ing a fiber that never blocked
19
21
 
20
22
  # Don't pass *args and **opts to an unknown fiber scheduler class.
21
- super() do
23
+ fiber = super() do
22
24
  Compatibility.set_internal!
23
25
  yield
24
26
  ensure
@@ -31,15 +33,23 @@ class FiberScheduler
31
33
  block(nil, nil)
32
34
  end
33
35
 
36
+ fiber
37
+
34
38
  when :fleeting
35
- # Transfer to current fiber some time - after a fleeting fiber yields.
39
+ # Transfer to current fiber some time after a fleeting fiber yields.
36
40
  unblock(nil, Fiber.current)
37
41
  # Alternative to #unblock: Fiber.scheduler.push(Fiber.current)
38
42
 
39
- Fiber.new(blocking: false) {
43
+ fiber = Fiber.new(blocking: false) do
40
44
  Compatibility.set_internal!
41
45
  yield
42
- }.transfer
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)
43
53
 
44
54
  when nil
45
55
  # Don't pass *args and **opts to an unknown fiber scheduler class.
@@ -53,6 +63,28 @@ class FiberScheduler
53
63
  end
54
64
  end
55
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
81
+ end
82
+ end
83
+
84
+ def _fleeting
85
+ @_fleeting ||= {}
86
+ end
87
+
56
88
  def self.set_internal!
57
89
  Thread.current[:_fiber_scheduler] = true # Sets a FIBER local var!
58
90
  end
@@ -1,3 +1,3 @@
1
1
  class FiberScheduler
2
- VERSION = "0.11.0".freeze
2
+ VERSION = "0.12.0".freeze
3
3
  end
@@ -12,12 +12,10 @@ end
12
12
  module Kernel
13
13
  def FiberScheduler(type = nil, &block)
14
14
  if Fiber.scheduler.nil?
15
- scheduler = FiberScheduler.new
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
@@ -48,7 +46,7 @@ module Kernel
48
46
  finished = false # prevents races
49
47
  blocking = false # prevents #unblock-ing a fiber that never blocked
50
48
 
51
- Fiber.schedule do
49
+ fiber = Fiber.schedule do
52
50
  FiberScheduler::Compatibility.set_internal!
53
51
  yield
54
52
  ensure
@@ -67,7 +65,22 @@ module Kernel
67
65
  blocking = true
68
66
  scheduler.block(nil, nil)
69
67
  end
68
+
69
+ fiber
70
+
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)
71
84
 
72
85
  when nil
73
86
  Fiber.schedule do
@@ -181,6 +194,7 @@ class FiberScheduler
181
194
  case type
182
195
  when :blocking
183
196
  Fiber.new(blocking: true, &block).tap(&:resume)
197
+
184
198
  when :waiting
185
199
  finished = false # prevents races
186
200
  fiber = Fiber.new(blocking: false) do
@@ -206,6 +220,7 @@ class FiberScheduler
206
220
  end
207
221
 
208
222
  fiber
223
+
209
224
  when :fleeting
210
225
  if current != @fiber
211
226
  # nested Fiber.schedule
@@ -213,6 +228,7 @@ class FiberScheduler
213
228
  end
214
229
 
215
230
  Fiber.new(blocking: false, &block).tap(&:transfer)
231
+
216
232
  when nil
217
233
  if current != @fiber
218
234
  # nested Fiber.schedule
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiber_scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Sutic
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: fiber_scheduler_spec
29
29
  requirement: !ruby/object:Gem::Requirement
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