polyphony 0.74 → 0.75

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: 2948e34f11b2bcb60406fda1024cac8d93c9019edfc97a8febe083d503b56d88
4
- data.tar.gz: 4bedbe795bbdb669123da5d4d671e78e6cfe3a021ddf13f2a80563a80ca92571
3
+ metadata.gz: 25015dd770af4d3b375af0625cfe9fe98becb328a0e77abb3101be2580279a7c
4
+ data.tar.gz: e2227ea3fa7d3ec04f5b580afdc92b9d7aacbab76b9e17dd0b86fb5e4e5b6a6f
5
5
  SHA512:
6
- metadata.gz: 36cf3fecb1b3ad6dc7aec6a5a12b2a0db5e7e4f2fc15a201c5e6dbe692a3ebcf5d62bc8aad8febfb224c393014c40090245c47c93dec8b41bd9732b6002c9a8f
7
- data.tar.gz: 8ad3f84d0af1eb5bb1535eb53128fb4f0602491e673128a873c8ef5176735ed61c6e1c53eb0b5faeb0792e299e771321a204f42d588566274f1737f16281a09e
6
+ metadata.gz: 967f6aa30621aae39dafdb587c28e1c0ec96685fc82972adb19fb50de7adfaaa42ce861c0f941f85ad536e29b459251d22c34a6bd96f8fc89f23dd4c0ecac47a
7
+ data.tar.gz: b3d6884d859c4eb61ca1d8bc8d1b727a5bf66c6c1af5280896264414bf14654650a1d8bcf3a6b744d235f5dd435e9231a0e047f95a17bfb7ce1642791c347c05
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 0.75 2022-02-04
2
+
3
+ - Fix handling of MoveOn on main fiber of forked process
4
+ - Ensure SSLSocket underlying socket is in nonblocking mode
5
+ - Add `Polyphony.backend_verify_blocking_mode` API
6
+ - Fix address resolution for hostnames with IPv6 address
7
+ - Improve behaviour of OOB fiber
8
+ - Include caller in `fiber_switchpoint` trace
9
+
1
10
  ## 0.74 2022-02-01
2
11
 
3
12
  - Add support for IPv6 (#69)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polyphony (0.74)
4
+ polyphony (0.75)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -64,7 +64,8 @@ VALUE backend_base_switch_fiber(VALUE backend, struct Backend_base *base) {
64
64
  unsigned int idle_tasks_run_count = 0;
65
65
 
66
66
  base->switch_count++;
67
- COND_TRACE(base, 2, SYM_fiber_switchpoint, current_fiber);
67
+ if (SHOULD_TRACE(base))
68
+ TRACE(base, 3, SYM_fiber_switchpoint, current_fiber, CALLER());
68
69
 
69
70
  while (1) {
70
71
  next = runqueue_shift(&base->runqueue);
@@ -415,6 +416,13 @@ VALUE Backend_stats(VALUE self) {
415
416
  return stats;
416
417
  }
417
418
 
419
+ VALUE Backend_verify_blocking_mode(VALUE self, VALUE io, VALUE blocking) {
420
+ rb_io_t *fptr;
421
+ GetOpenFile(io, fptr);
422
+ io_verify_blocking_mode(fptr, io, blocking);
423
+ return self;
424
+ }
425
+
418
426
  void backend_setup_stats_symbols() {
419
427
  SYM_runqueue_size = ID2SYM(rb_intern("runqueue_size"));
420
428
  SYM_runqueue_length = ID2SYM(rb_intern("runqueue_length"));
@@ -112,6 +112,7 @@ VALUE Backend_timeout_ensure_safe(VALUE arg);
112
112
  VALUE Backend_timeout_ensure_safe(VALUE arg);
113
113
  VALUE Backend_sendv(VALUE self, VALUE io, VALUE ary, VALUE flags);
114
114
  VALUE Backend_stats(VALUE self);
115
+ VALUE Backend_verify_blocking_mode(VALUE self, VALUE io, VALUE blocking);
115
116
  void backend_run_idle_tasks(struct Backend_base *base);
116
117
  void io_verify_blocking_mode(rb_io_t *fptr, VALUE io, VALUE blocking);
117
118
  void backend_setup_stats_symbols();
@@ -154,6 +154,7 @@ void Init_Polyphony() {
154
154
  rb_define_singleton_method(mPolyphony, "backend_waitpid", Polyphony_backend_waitpid, 1);
155
155
  rb_define_singleton_method(mPolyphony, "backend_write", Polyphony_backend_write, -1);
156
156
  rb_define_singleton_method(mPolyphony, "backend_close", Polyphony_backend_close, 1);
157
+ rb_define_singleton_method(mPolyphony, "backend_verify_blocking_mode", Backend_verify_blocking_mode, 2);
157
158
 
158
159
  rb_define_global_function("snooze", Polyphony_snooze, 0);
159
160
  rb_define_global_function("suspend", Polyphony_suspend, 0);
@@ -10,7 +10,8 @@
10
10
  // debugging
11
11
  #define OBJ_ID(obj) (NUM2LONG(rb_funcall(obj, rb_intern("object_id"), 0)))
12
12
  #define INSPECT(str, obj) { printf(str); VALUE s = rb_funcall(obj, rb_intern("inspect"), 0); printf(": %s\n", StringValueCStr(s)); }
13
- #define TRACE_CALLER() { VALUE c = rb_funcall(rb_mKernel, rb_intern("caller"), 0); INSPECT("caller: ", c); }
13
+ #define CALLER() rb_funcall(rb_mKernel, rb_intern("caller"), 0)
14
+ #define TRACE_CALLER() INSPECT("caller: ", CALLER())
14
15
  #define TRACE_C_STACK() { \
15
16
  void *entries[10]; \
16
17
  size_t size = backtrace(entries, 10); \
@@ -250,10 +250,18 @@ module Polyphony
250
250
  def schedule_priority_oob_fiber(&block)
251
251
  f = Fiber.new do
252
252
  Fiber.current.setup_raw
253
- block.call
253
+ result = block.call
254
254
  rescue Exception => e
255
255
  Thread.current.schedule_and_wakeup(Thread.main.main_fiber, e)
256
+ result = e
257
+ ensure
258
+ Thread.backend.trace(:fiber_terminate, f, result)
259
+ suspend
256
260
  end
261
+ f.oob = true
262
+ location = block.source_location
263
+ f.set_caller(["#{location.join(':')}"])
264
+ Thread.backend.trace(:fiber_create, f)
257
265
  Thread.current.schedule_and_wakeup(f, nil)
258
266
  end
259
267
  end
@@ -449,7 +457,7 @@ class ::Fiber
449
457
 
450
458
  extend Polyphony::FiberControlClassMethods
451
459
 
452
- attr_accessor :tag, :thread, :parent
460
+ attr_accessor :tag, :thread, :parent, :oob
453
461
  attr_reader :result
454
462
 
455
463
  def running?
@@ -466,7 +474,11 @@ class ::Fiber
466
474
  alias_method :to_s, :inspect
467
475
 
468
476
  def location
469
- @caller ? @caller[0] : '(root)'
477
+ if @oob
478
+ "#{@caller[0]} (oob)"
479
+ else
480
+ @caller ? @caller[0] : '(root)'
481
+ end
470
482
  end
471
483
 
472
484
  def caller
@@ -478,6 +490,10 @@ class ::Fiber
478
490
  end
479
491
  end
480
492
 
493
+ def set_caller(o)
494
+ @caller = o
495
+ end
496
+
481
497
  def main?
482
498
  @main
483
499
  end
@@ -38,8 +38,10 @@ class ::OpenSSL::SSL::SSLSocket
38
38
 
39
39
  alias_method :orig_sysread, :sysread
40
40
  def sysread(maxlen, buf = +'')
41
+ # ensure socket is non blocking
42
+ Polyphony.backend_verify_blocking_mode(io, false)
41
43
  while true
42
- case (result = read_nonblock(maxlen, buf, exception: false))
44
+ case (result = sysread_nonblock(maxlen, buf, exception: false))
43
45
  when :wait_readable then Polyphony.backend_wait_io(io, false)
44
46
  when :wait_writable then Polyphony.backend_wait_io(io, true)
45
47
  else return result
@@ -49,6 +51,8 @@ class ::OpenSSL::SSL::SSLSocket
49
51
 
50
52
  alias_method :orig_syswrite, :syswrite
51
53
  def syswrite(buf)
54
+ # ensure socket is non blocking
55
+ Polyphony.backend_verify_blocking_mode(io, false)
52
56
  while true
53
57
  case (result = write_nonblock(buf, exception: false))
54
58
  when :wait_readable then Polyphony.backend_wait_io(io, false)
@@ -124,12 +124,9 @@ class ::TCPSocket
124
124
  new(*args)
125
125
  end
126
126
 
127
- def address_family(host)
128
- host =~ /\:\:/ ? Socket::AF_INET6 : Socket::AF_INET
129
- end
130
-
131
127
  def initialize(remote_host, remote_port, local_host = nil, local_port = nil)
132
- @io = Socket.new address_family(remote_host), Socket::SOCK_STREAM
128
+ remote_addr = Addrinfo.tcp(remote_host, remote_port)
129
+ @io = Socket.new remote_addr.afamily, Socket::SOCK_STREAM
133
130
  if local_host && local_port
134
131
  addr = Addrinfo.tcp(local_host, local_port)
135
132
  @io.bind(addr)
@@ -231,13 +228,10 @@ end
231
228
 
232
229
  # Override stock TCPServer code by encapsulating a Socket instance.
233
230
  class ::TCPServer
234
- def address_family(host)
235
- host =~ /\:\:/ ? Socket::AF_INET6 : Socket::AF_INET
236
- end
237
-
238
231
  def initialize(hostname = nil, port = 0)
239
- @io = Socket.new address_family(hostname), Socket::SOCK_STREAM
240
- @io.bind(Addrinfo.tcp(hostname, port))
232
+ addr = Addrinfo.tcp(hostname, port)
233
+ @io = Socket.new addr.afamily, Socket::SOCK_STREAM
234
+ @io.bind(addr)
241
235
  @io.listen(0)
242
236
  end
243
237
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.74'
4
+ VERSION = '0.75'
5
5
  end
data/lib/polyphony.rb CHANGED
@@ -41,6 +41,8 @@ module Polyphony
41
41
  run_forked_block(&block)
42
42
  rescue SystemExit
43
43
  # fall through to ensure
44
+ rescue Polyphony::MoveOn
45
+ exit!
44
46
  rescue Exception => e
45
47
  STDERR << e.full_message
46
48
  exit!
data/test/helper.rb CHANGED
@@ -21,10 +21,6 @@ IS_LINUX = RUBY_PLATFORM =~ /linux/
21
21
  # Minitest::Reporters::SpecReporter.new
22
22
  # ]
23
23
 
24
- class ::Fiber
25
- attr_writer :auto_watcher
26
- end
27
-
28
24
  module ::Kernel
29
25
  def trace(*args)
30
26
  STDOUT.orig_write(format_trace(args))
@@ -59,7 +55,6 @@ class MiniTest::Test
59
55
  puts "Children left after #{self.name}: #{Fiber.current.children.inspect}"
60
56
  exit!
61
57
  end
62
- Fiber.current.instance_variable_set(:@auto_watcher, nil)
63
58
  rescue => e
64
59
  puts e
65
60
  puts e.backtrace.join("\n")
data/test/test_thread.rb CHANGED
@@ -132,7 +132,7 @@ class ThreadTest < MiniTest::Test
132
132
  Thread.backend.trace_proc = proc {|*r| records << r }
133
133
  suspend
134
134
  assert_equal [
135
- [:fiber_switchpoint, Fiber.current]
135
+ [:fiber_switchpoint, Fiber.current, ["#{__FILE__}:#{__LINE__ - 2}:in `test_that_suspend_returns_immediately_if_no_watchers'"] + caller]
136
136
  ], records
137
137
  ensure
138
138
  Thread.backend.trace_proc = nil
data/test/test_trace.rb CHANGED
@@ -10,7 +10,7 @@ class TraceTest < MiniTest::Test
10
10
 
11
11
  assert_equal [
12
12
  [:fiber_schedule, Fiber.current, nil, false],
13
- [:fiber_switchpoint, Fiber.current],
13
+ [:fiber_switchpoint, Fiber.current, ["#{__FILE__}:#{__LINE__ - 4}:in `test_tracing_enabled'"] + caller],
14
14
  [:fiber_run, Fiber.current, nil]
15
15
  ], events
16
16
  ensure
@@ -22,9 +22,15 @@ class TraceTest < MiniTest::Test
22
22
  Thread.backend.trace_proc = proc { |*e| events << e }
23
23
 
24
24
  f = spin { sleep 0; :byebye }
25
+ l0 = __LINE__ + 1
25
26
  suspend
26
27
  sleep 0
27
28
 
29
+ Thread.backend.trace_proc = nil
30
+
31
+ # remove caller info for :fiber_switchpoint events
32
+ events.each {|e| e.pop if e[0] == :fiber_switchpoint }
33
+
28
34
  assert_equal [
29
35
  [:fiber_create, f],
30
36
  [:fiber_schedule, f, nil, false],
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.74'
4
+ version: '0.75'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-01 00:00:00.000000000 Z
11
+ date: 2022-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -136,7 +136,7 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: 1.1.4
139
- description:
139
+ description:
140
140
  email: sharon@noteflakes.com
141
141
  executables: []
142
142
  extensions:
@@ -412,7 +412,7 @@ metadata:
412
412
  documentation_uri: https://digital-fabric.github.io/polyphony/
413
413
  homepage_uri: https://digital-fabric.github.io/polyphony/
414
414
  changelog_uri: https://github.com/digital-fabric/polyphony/blob/master/CHANGELOG.md
415
- post_install_message:
415
+ post_install_message:
416
416
  rdoc_options:
417
417
  - "--title"
418
418
  - polyphony
@@ -431,8 +431,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
431
431
  - !ruby/object:Gem::Version
432
432
  version: '0'
433
433
  requirements: []
434
- rubygems_version: 3.3.3
435
- signing_key:
434
+ rubygems_version: 3.2.32
435
+ signing_key:
436
436
  specification_version: 4
437
437
  summary: Fine grained concurrency for Ruby
438
438
  test_files: []