polyphony 0.47.2 → 0.47.3

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 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