polyphony 0.36 → 0.38

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/Gemfile +0 -11
  4. data/Gemfile.lock +1 -3
  5. data/Rakefile +4 -0
  6. data/TODO.md +12 -10
  7. data/docs/index.md +2 -1
  8. data/examples/core/xx-fork-cleanup.rb +22 -0
  9. data/ext/gyro/async.c +27 -13
  10. data/ext/gyro/child.c +29 -15
  11. data/ext/gyro/fiber.c +3 -1
  12. data/ext/gyro/gyro.c +0 -6
  13. data/ext/gyro/gyro.h +6 -0
  14. data/ext/gyro/io.c +24 -9
  15. data/ext/gyro/queue.c +21 -21
  16. data/ext/gyro/selector.c +23 -0
  17. data/ext/gyro/signal.c +24 -9
  18. data/ext/gyro/thread.c +12 -2
  19. data/ext/gyro/timer.c +33 -18
  20. data/lib/polyphony.rb +27 -36
  21. data/lib/polyphony/adapters/fs.rb +1 -4
  22. data/lib/polyphony/adapters/process.rb +29 -25
  23. data/lib/polyphony/adapters/trace.rb +129 -124
  24. data/lib/polyphony/core/channel.rb +36 -36
  25. data/lib/polyphony/core/exceptions.rb +29 -29
  26. data/lib/polyphony/core/global_api.rb +92 -91
  27. data/lib/polyphony/core/resource_pool.rb +84 -84
  28. data/lib/polyphony/core/sync.rb +17 -17
  29. data/lib/polyphony/core/thread_pool.rb +49 -37
  30. data/lib/polyphony/core/throttler.rb +25 -25
  31. data/lib/polyphony/extensions/core.rb +3 -3
  32. data/lib/polyphony/extensions/fiber.rb +269 -267
  33. data/lib/polyphony/extensions/openssl.rb +1 -1
  34. data/lib/polyphony/extensions/socket.rb +2 -1
  35. data/lib/polyphony/extensions/thread.rb +3 -3
  36. data/lib/polyphony/net.rb +71 -67
  37. data/lib/polyphony/version.rb +1 -1
  38. data/polyphony.gemspec +0 -3
  39. data/test/stress.rb +17 -12
  40. data/test/test_thread.rb +1 -0
  41. data/test/test_thread_pool.rb +2 -2
  42. data/test/test_throttler.rb +0 -1
  43. metadata +3 -16
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'openssl'
4
4
 
5
- import('./socket')
5
+ require_relative './socket'
6
6
 
7
7
  # Open ssl socket helper methods (to make it compatible with Socket API)
8
8
  class ::OpenSSL::SSL::SSLSocket
@@ -2,7 +2,8 @@
2
2
 
3
3
  require 'socket'
4
4
 
5
- import('./io')
5
+ require_relative './io'
6
+ require_relative '../core/thread_pool'
6
7
 
7
8
  # Socket overrides (eventually rewritten in C)
8
9
  class ::Socket
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- Exceptions = import '../core/exceptions'
3
+ require_relative '../core/exceptions'
4
4
 
5
5
  # Thread extensions
6
6
  class ::Thread
@@ -19,7 +19,7 @@ class ::Thread
19
19
  setup
20
20
  @ready = true
21
21
  result = @block.(*@args)
22
- rescue Exceptions::MoveOn, Exceptions::Terminate => e
22
+ rescue Polyphony::MoveOn, Polyphony::Terminate => e
23
23
  result = e.value
24
24
  rescue Exception => e
25
25
  result = e
@@ -78,7 +78,7 @@ class ::Thread
78
78
 
79
79
  alias_method :orig_kill, :kill
80
80
  def kill
81
- raise Exceptions::Terminate
81
+ raise Polyphony::Terminate
82
82
  end
83
83
 
84
84
  alias_method :orig_inspect, :inspect
data/lib/polyphony/net.rb CHANGED
@@ -1,73 +1,77 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- export :tcp_connect,
4
- :tcp_listen
3
+ require_relative './extensions/socket'
4
+ require_relative './extensions/openssl'
5
5
 
6
- import('./extensions/socket')
7
- import('./extensions/openssl')
8
-
9
- def tcp_connect(host, port, opts = {})
10
- socket = ::Socket.new(:INET, :STREAM).tap do |s|
11
- addr = ::Socket.sockaddr_in(port, host)
12
- s.connect(addr)
13
- end
14
- if opts[:secure_context] || opts[:secure]
15
- secure_socket(socket, opts[:secure_context], opts.merge(host: host))
16
- else
17
- socket
18
- end
19
- end
20
-
21
- def tcp_listen(host = nil, port = nil, opts = {})
22
- host ||= '0.0.0.0'
23
- raise 'Port number not specified' unless port
24
-
25
- socket = socket_from_options(host, port, opts)
26
- if opts[:secure_context] || opts[:secure]
27
- secure_server(socket, opts[:secure_context], opts)
28
- else
29
- socket
30
- end
31
- end
32
-
33
- def socket_from_options(host, port, opts)
34
- ::Socket.new(:INET, :STREAM).tap do |s|
35
- s.reuse_addr if opts[:reuse_addr]
36
- s.dont_linger if opts[:dont_linger]
37
- addr = ::Socket.sockaddr_in(port, host)
38
- s.bind(addr)
39
- s.listen(0)
40
- end
41
- end
42
-
43
- def secure_socket(socket, context, opts)
44
- context ||= OpenSSL::SSL::SSLContext.new
45
- setup_alpn(context, opts[:alpn_protocols]) if opts[:alpn_protocols]
46
- socket = secure_socket_wrapper(socket, context)
47
-
48
- socket.tap do |s|
49
- s.hostname = opts[:host] if opts[:host]
50
- s.connect
51
- s.post_connection_check(opts[:host]) if opts[:host]
52
- end
53
- end
54
-
55
- def secure_socket_wrapper(socket, context)
56
- if context
57
- OpenSSL::SSL::SSLSocket.new(socket, context)
58
- else
59
- OpenSSL::SSL::SSLSocket.new(socket)
6
+ module Polyphony
7
+ module Net
8
+ class << self
9
+ def tcp_connect(host, port, opts = {})
10
+ socket = ::Socket.new(:INET, :STREAM).tap do |s|
11
+ addr = ::Socket.sockaddr_in(port, host)
12
+ s.connect(addr)
13
+ end
14
+ if opts[:secure_context] || opts[:secure]
15
+ secure_socket(socket, opts[:secure_context], opts.merge(host: host))
16
+ else
17
+ socket
18
+ end
19
+ end
20
+
21
+ def tcp_listen(host = nil, port = nil, opts = {})
22
+ host ||= '0.0.0.0'
23
+ raise 'Port number not specified' unless port
24
+
25
+ socket = socket_from_options(host, port, opts)
26
+ if opts[:secure_context] || opts[:secure]
27
+ secure_server(socket, opts[:secure_context], opts)
28
+ else
29
+ socket
30
+ end
31
+ end
32
+
33
+ def socket_from_options(host, port, opts)
34
+ ::Socket.new(:INET, :STREAM).tap do |s|
35
+ s.reuse_addr if opts[:reuse_addr]
36
+ s.dont_linger if opts[:dont_linger]
37
+ addr = ::Socket.sockaddr_in(port, host)
38
+ s.bind(addr)
39
+ s.listen(0)
40
+ end
41
+ end
42
+
43
+ def secure_socket(socket, context, opts)
44
+ context ||= OpenSSL::SSL::SSLContext.new
45
+ setup_alpn(context, opts[:alpn_protocols]) if opts[:alpn_protocols]
46
+ socket = secure_socket_wrapper(socket, context)
47
+
48
+ socket.tap do |s|
49
+ s.hostname = opts[:host] if opts[:host]
50
+ s.connect
51
+ s.post_connection_check(opts[:host]) if opts[:host]
52
+ end
53
+ end
54
+
55
+ def secure_socket_wrapper(socket, context)
56
+ if context
57
+ OpenSSL::SSL::SSLSocket.new(socket, context)
58
+ else
59
+ OpenSSL::SSL::SSLSocket.new(socket)
60
+ end
61
+ end
62
+
63
+ def secure_server(socket, context, opts)
64
+ setup_alpn(context, opts[:alpn_protocols]) if opts[:alpn_protocols]
65
+ OpenSSL::SSL::SSLServer.new(socket, context)
66
+ end
67
+
68
+ def setup_alpn(context, protocols)
69
+ context.alpn_protocols = protocols
70
+ context.alpn_select_cb = lambda do |peer_protocols|
71
+ (protocols & peer_protocols).first
72
+ end
73
+ end
74
+ end
60
75
  end
61
76
  end
62
77
 
63
- def secure_server(socket, context, opts)
64
- setup_alpn(context, opts[:alpn_protocols]) if opts[:alpn_protocols]
65
- OpenSSL::SSL::SSLServer.new(socket, context)
66
- end
67
-
68
- def setup_alpn(context, protocols)
69
- context.alpn_protocols = protocols
70
- context.alpn_select_cb = lambda do |peer_protocols|
71
- (protocols & peer_protocols).first
72
- end
73
- end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.36'
4
+ VERSION = '0.38'
5
5
  end
data/polyphony.gemspec CHANGED
@@ -21,8 +21,6 @@ Gem::Specification.new do |s|
21
21
  s.require_paths = ["lib"]
22
22
  s.required_ruby_version = '>= 2.6'
23
23
 
24
- s.add_runtime_dependency 'modulation', '~>1.0'
25
-
26
24
  s.add_development_dependency 'httparty', '0.17.0'
27
25
  s.add_development_dependency 'localhost', '1.1.4'
28
26
  s.add_development_dependency 'minitest', '5.13.0'
@@ -39,5 +37,4 @@ Gem::Specification.new do |s|
39
37
  s.add_development_dependency 'jekyll-remote-theme', '~>0.4.1'
40
38
  s.add_development_dependency 'jekyll-seo-tag', '~>2.6.1'
41
39
  s.add_development_dependency 'just-the-docs', '~>0.2.7'
42
-
43
40
  end
data/test/stress.rb CHANGED
@@ -1,20 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- @count = 0
3
+ count = ARGV[0] ? ARGV[0].to_i : 100
4
4
 
5
- def run_tests
6
- @count += 1
7
- puts "!(#{@count})"
8
- # output = `ruby test/test_thread.rb -n test_thread_inspect`
9
- system('ruby test/run.rb')
5
+ TEST_CMD = 'ruby test/run.rb'
6
+
7
+ def run_test(count)
8
+ puts "#{count}: running tests..."
9
+ system(TEST_CMD)
10
10
  return if $?.exitstatus == 0
11
11
 
12
+ puts "Failure after #{count} tests"
12
13
  exit!
13
- # puts
14
- # puts output
15
- # exit!
16
14
  end
17
15
 
18
- loop {
19
- run_tests
20
- }
16
+ trap('INT') { exit! }
17
+ t0 = Time.now
18
+ count.times { |i| run_test(i + 1) }
19
+ elapsed = Time.now - t0
20
+ puts format(
21
+ "Successfully ran %d tests in %f seconds (%f per test)",
22
+ count,
23
+ elapsed,
24
+ elapsed / count
25
+ )
data/test/test_thread.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'helper'
4
+ require 'polyphony/adapters/trace'
4
5
 
5
6
  class ThreadTest < MiniTest::Test
6
7
  def test_thread_spin
@@ -25,7 +25,7 @@ class ThreadPoolTest < MiniTest::Test
25
25
  threads = []
26
26
  results = []
27
27
 
28
- 10.times do |i|
28
+ 15.times do |i|
29
29
  spin do
30
30
  results << @pool.process do
31
31
  threads << Thread.current
@@ -38,7 +38,7 @@ class ThreadPoolTest < MiniTest::Test
38
38
  suspend
39
39
 
40
40
  assert_equal @pool.size, threads.uniq.size
41
- assert_equal (0..9).map { |i| i * 10}, results.sort
41
+ assert_equal (0..14).map { |i| i * 10}, results.sort
42
42
  end
43
43
 
44
44
  def test_process_with_exception
@@ -24,7 +24,6 @@ class ThrottlerTest < MiniTest::Test
24
24
  end
25
25
  sleep 0.25
26
26
  f.stop
27
- puts "count: #{buffer.size}"
28
27
  assert (2..6).include?(buffer.size)
29
28
  ensure
30
29
  t.stop
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polyphony
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.36'
4
+ version: '0.38'
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-03-31 00:00:00.000000000 Z
11
+ date: 2020-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: modulation
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: httparty
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -318,6 +304,7 @@ files:
318
304
  - examples/core/xx-deferring-an-operation.rb
319
305
  - examples/core/xx-erlang-style-genserver.rb
320
306
  - examples/core/xx-exception-backtrace.rb
307
+ - examples/core/xx-fork-cleanup.rb
321
308
  - examples/core/xx-fork-spin.rb
322
309
  - examples/core/xx-fork-terminate.rb
323
310
  - examples/core/xx-forking.rb