polyphony 0.47.2 → 0.47.3

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: 8f9e7ffec31a2009f8000e7b88473e21581de37640ee2d5c6357550883d7bc7c
4
- data.tar.gz: d3f8262b8373e7a337dacc0c8e04b1b25ddf0254445b146787a5aa82520dee30
3
+ metadata.gz: 89890bc8a81fd4f0a80f6d84c7f5138cfda12bc99848e74ef8140abf681640e2
4
+ data.tar.gz: d18e210b24f3d0eb2f83c1dcb188e7c1c691f949231ef0b3d07bd926c988f4d6
5
5
  SHA512:
6
- metadata.gz: 0203bd8d66851f3eeed446f7537183e5b66a422f5f5c68b79a1b99f5c3762e243d1027cd77ccbe255012b9450a56b336c9da2e78e91b867adee8f3353351db7c
7
- data.tar.gz: 74ef01b9828d4ba0c6a67cd8a402551484c935234fb7d259146d6cfd5033149f7376aa98068dc8f30168c0ec783015208326455795926d02b385e1bda27d1f37
6
+ metadata.gz: c95bef00de396f601f91937c780202a26d0e9c5a3eb48f564d1dcb70d89b30c12ebbbc89c9ddb10b81b013f9a89398468b8b3b4c1d3158d00110e3e6ea5355a6
7
+ data.tar.gz: 3c31dac6a239e73b6dbf028edfeced82ac6b2d17ba2f5f2960a41aa9d74e57336082bbe038a8ed6701a2ceefaf68cacb74764f9f71c81ce1e36d5868702e5346
@@ -1,3 +1,8 @@
1
+ ## 0.47.3
2
+
3
+ * Enable I/O in signal handlers (#45)
4
+ * Accept `:interval` argument in `#spin_loop`
5
+
1
6
  ## 0.47.2
2
7
 
3
8
  * Fix API compatibility between TCPSocket and IO
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polyphony (0.47.2)
4
+ polyphony (0.47.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/TODO.md CHANGED
@@ -1,3 +1,35 @@
1
+ Graceful shutdown again:
2
+
3
+ - Add `Polyphony::GracefulShutdown` exception
4
+ - Two exceptions for stopping fibers:
5
+ - `Polyphony::GracefulShutdown` - graceful shutdown
6
+ - `Polyphony::Terminate` - ungraceful shutdown
7
+ - Fiber API:
8
+ - `Fiber#shutdown_children` - graceful shutdown of all children
9
+ - `Fiber#terminate_children` - ungraceful shutdown of all children
10
+
11
+ - Add `Fiber#graceful_shutdown?` method
12
+ - Returns false unless a `Polyphony::GracefulShutdown` was raised
13
+ - Override `Polyphony::Terminate#invoke` to reset the `@graceful_shutdown` fiber
14
+ flag
15
+
16
+ And then we have:
17
+
18
+ ```ruby
19
+ spin do
20
+ loop { do_some_stuff }
21
+ ensure
22
+ return unless Fiber.current.graceful_shutdown?
23
+
24
+ shutdown_gracefully
25
+ end
26
+ ```
27
+
28
+ - When a fiber is stopped it should use `Polyphony::Terminate` to stop child
29
+ fibers, *unless* it was stopped with a `Polyphony::GracefulShutdown` (which it
30
+ can check with `@graceful_shutdown`).
31
+
32
+
1
33
  ## Roadmap for Polyphony 1.0
2
34
 
3
35
  - Check why worker-thread example doesn't work.
@@ -53,10 +53,10 @@ module Polyphony
53
53
  Fiber.current.spin(tag, caller, &block)
54
54
  end
55
55
 
56
- def spin_loop(tag = nil, rate: nil, &block)
57
- if rate
56
+ def spin_loop(tag = nil, rate: nil, interval: nil, &block)
57
+ if rate || interval
58
58
  Fiber.current.spin(tag, caller) do
59
- throttled_loop(rate, &block)
59
+ throttled_loop(rate: rate, interval: interval, &block)
60
60
  end
61
61
  else
62
62
  Fiber.current.spin(tag, caller) { loop(&block) }
@@ -73,17 +73,8 @@ module Polyphony
73
73
  end.await
74
74
  end
75
75
 
76
- def every(interval)
77
- next_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) + interval
78
- loop do
79
- now = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
80
- Thread.current.backend.sleep(next_time - now)
81
- yield
82
- loop do
83
- next_time += interval
84
- break if next_time > now
85
- end
86
- end
76
+ def every(interval, &block)
77
+ Thread.current.backend.timer_loop(interval, &block)
87
78
  end
88
79
 
89
80
  def move_on_after(interval, with_value: nil, &block)
@@ -58,18 +58,7 @@ module Polyphony
58
58
  # Discards the currently-acquired resource
59
59
  # instead of returning it to the pool when done.
60
60
  def discard!
61
- if block_given?
62
- @size.times do
63
- acquire do |r|
64
- next if yield(r)
65
-
66
- @size -= 1
67
- @acquired_resources.delete(Fiber.current)
68
- end
69
- end
70
- else
71
- @size -= 1 if @acquired_resources.delete(Fiber.current)
72
- end
61
+ @size -= 1 if @acquired_resources.delete(Fiber.current)
73
62
  end
74
63
 
75
64
  def preheat!
@@ -173,6 +173,7 @@ module Polyphony
173
173
  # signals (see also the patched `Kernel#trap`)
174
174
  def schedule_priority_oob_fiber(&block)
175
175
  f = Fiber.new do
176
+ Fiber.current.setup_raw
176
177
  block.call
177
178
  rescue Exception => e
178
179
  Thread.current.schedule_and_wakeup(Thread.main.main_fiber, e)
@@ -262,6 +263,7 @@ module Polyphony
262
263
  # allows the fiber to be scheduled and to receive messages.
263
264
  def setup_raw
264
265
  @thread = Thread.current
266
+ @running = true
265
267
  end
266
268
 
267
269
  def setup_main_fiber
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.47.2'
4
+ VERSION = '0.47.3'
5
5
  end
@@ -210,7 +210,7 @@ class CancelAfterTest < MiniTest::Test
210
210
  sleep 0.007
211
211
  end
212
212
  t1 = Time.now
213
- assert_in_range 0.014..0.02, t1 - t0
213
+ assert_in_range 0.014..0.024, t1 - t0
214
214
  end
215
215
 
216
216
  class CustomException < Exception
@@ -297,6 +297,16 @@ class SpinLoopTest < MiniTest::Test
297
297
  f.stop
298
298
  assert_in_range 1..3, counter
299
299
  end
300
+
301
+ def test_spin_loop_with_interval
302
+ buffer = []
303
+ counter = 0
304
+ t0 = Time.now
305
+ f = spin_loop(interval: 0.01) { buffer << (counter += 1) }
306
+ sleep 0.02
307
+ f.stop
308
+ assert_in_range 1..3, counter
309
+ end
300
310
  end
301
311
 
302
312
  class SpinScopeTest < MiniTest::Test
@@ -48,27 +48,6 @@ class ResourcePoolTest < MiniTest::Test
48
48
  assert_equal 1, pool.size
49
49
  end
50
50
 
51
- def test_discard_with_block
52
- resources = [+'a', +'b', +'c', +'d', +'e', +'f']
53
- pool = Polyphony::ResourcePool.new(limit: 4) { resources.shift }
54
-
55
- buffer = []
56
- (1..4).each do |i|
57
- spin do
58
- 3.times do
59
- pool.acquire { |r| buffer << [i, r]; trace [i]; snooze }
60
- end
61
- end
62
- end
63
-
64
- 2.times { trace [0]; snooze }
65
- assert_equal [[1, 'a'], [2, 'b'], [3, 'c'], [4, 'd']], buffer
66
-
67
- pool.discard! { |r| r == 'a' || r == 'c' }
68
- 2.times { trace [0]; snooze }
69
- assert_equal [[1, 'a'], [2, 'b'], [3, 'c'], [4, 'd'], [1, 'b'], [2, 'd'], [3, 'e'], [4, 'f']], buffer
70
- end
71
-
72
51
  def test_single_resource_limit
73
52
  resources = [+'a', +'b']
74
53
  pool = Polyphony::ResourcePool.new(limit: 1) { resources.shift }
@@ -76,4 +76,22 @@ class SignalTrapTest < Minitest::Test
76
76
  buffer = i.read
77
77
  assert_equal "3-interrupt\n", buffer
78
78
  end
79
+
80
+ def test_io_in_signal_handler
81
+ i, o = IO.pipe
82
+ pid = Polyphony.fork do
83
+ trap('INT') { o.puts 'INT'; o.close; exit! }
84
+ i.close
85
+ sleep
86
+ ensure
87
+ o.close
88
+ end
89
+
90
+ o.close
91
+ sleep 0.1
92
+ Process.kill('INT', pid)
93
+ Thread.current.backend.waitpid(pid)
94
+ buffer = i.read
95
+ assert_equal "INT\n", buffer
96
+ end
79
97
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polyphony
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.47.2
4
+ version: 0.47.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-10 00:00:00.000000000 Z
11
+ date: 2020-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler