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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile +0 -11
- data/Gemfile.lock +1 -3
- data/Rakefile +4 -0
- data/TODO.md +12 -10
- data/docs/index.md +2 -1
- data/examples/core/xx-fork-cleanup.rb +22 -0
- data/ext/gyro/async.c +27 -13
- data/ext/gyro/child.c +29 -15
- data/ext/gyro/fiber.c +3 -1
- data/ext/gyro/gyro.c +0 -6
- data/ext/gyro/gyro.h +6 -0
- data/ext/gyro/io.c +24 -9
- data/ext/gyro/queue.c +21 -21
- data/ext/gyro/selector.c +23 -0
- data/ext/gyro/signal.c +24 -9
- data/ext/gyro/thread.c +12 -2
- data/ext/gyro/timer.c +33 -18
- data/lib/polyphony.rb +27 -36
- data/lib/polyphony/adapters/fs.rb +1 -4
- data/lib/polyphony/adapters/process.rb +29 -25
- data/lib/polyphony/adapters/trace.rb +129 -124
- data/lib/polyphony/core/channel.rb +36 -36
- data/lib/polyphony/core/exceptions.rb +29 -29
- data/lib/polyphony/core/global_api.rb +92 -91
- data/lib/polyphony/core/resource_pool.rb +84 -84
- data/lib/polyphony/core/sync.rb +17 -17
- data/lib/polyphony/core/thread_pool.rb +49 -37
- data/lib/polyphony/core/throttler.rb +25 -25
- data/lib/polyphony/extensions/core.rb +3 -3
- data/lib/polyphony/extensions/fiber.rb +269 -267
- data/lib/polyphony/extensions/openssl.rb +1 -1
- data/lib/polyphony/extensions/socket.rb +2 -1
- data/lib/polyphony/extensions/thread.rb +3 -3
- data/lib/polyphony/net.rb +71 -67
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +0 -3
- data/test/stress.rb +17 -12
- data/test/test_thread.rb +1 -0
- data/test/test_thread_pool.rb +2 -2
- data/test/test_throttler.rb +0 -1
- metadata +3 -16
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
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
|
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
|
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
|
-
|
4
|
-
|
3
|
+
require_relative './extensions/socket'
|
4
|
+
require_relative './extensions/openssl'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def tcp_connect(host, port, opts = {})
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
def tcp_listen(host = nil, port = nil, opts = {})
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
def socket_from_options(host, port, opts)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
def secure_socket(socket, context, opts)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
def secure_socket_wrapper(socket, context)
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
data/lib/polyphony/version.rb
CHANGED
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
|
-
|
3
|
+
count = ARGV[0] ? ARGV[0].to_i : 100
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
#
|
9
|
-
system(
|
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
|
-
|
19
|
-
|
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
data/test/test_thread_pool.rb
CHANGED
@@ -25,7 +25,7 @@ class ThreadPoolTest < MiniTest::Test
|
|
25
25
|
threads = []
|
26
26
|
results = []
|
27
27
|
|
28
|
-
|
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..
|
41
|
+
assert_equal (0..14).map { |i| i * 10}, results.sort
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_process_with_exception
|
data/test/test_throttler.rb
CHANGED
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.
|
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-
|
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
|