nio4r 1.2.1-java → 2.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rubocop.yml +31 -38
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +15 -14
  6. data/CHANGES.md +75 -42
  7. data/Gemfile +10 -5
  8. data/Guardfile +10 -0
  9. data/LICENSE.txt +1 -1
  10. data/README.md +57 -161
  11. data/Rakefile +2 -1
  12. data/examples/echo_server.rb +1 -0
  13. data/ext/libev/Changes +4 -13
  14. data/ext/libev/ev.c +101 -74
  15. data/ext/libev/ev.h +3 -3
  16. data/ext/libev/ev_epoll.c +6 -3
  17. data/ext/libev/ev_kqueue.c +8 -4
  18. data/ext/libev/ev_poll.c +6 -3
  19. data/ext/libev/ev_port.c +8 -4
  20. data/ext/libev/ev_select.c +4 -2
  21. data/ext/nio4r/bytebuffer.c +421 -0
  22. data/ext/nio4r/extconf.rb +2 -10
  23. data/ext/nio4r/monitor.c +93 -46
  24. data/ext/nio4r/nio4r.h +11 -13
  25. data/ext/nio4r/org/nio4r/ByteBuffer.java +295 -0
  26. data/ext/nio4r/org/nio4r/Monitor.java +164 -0
  27. data/ext/nio4r/org/nio4r/Nio4r.java +22 -391
  28. data/ext/nio4r/org/nio4r/Selector.java +278 -0
  29. data/ext/nio4r/selector.c +55 -53
  30. data/lib/nio.rb +4 -3
  31. data/lib/nio/bytebuffer.rb +222 -0
  32. data/lib/nio/monitor.rb +64 -4
  33. data/lib/nio/selector.rb +52 -20
  34. data/lib/nio/version.rb +1 -1
  35. data/nio4r.gemspec +25 -19
  36. data/spec/nio/acceptables_spec.rb +6 -4
  37. data/spec/nio/bytebuffer_spec.rb +349 -0
  38. data/spec/nio/monitor_spec.rb +122 -79
  39. data/spec/nio/selectables/pipe_spec.rb +5 -1
  40. data/spec/nio/selectables/ssl_socket_spec.rb +15 -12
  41. data/spec/nio/selectables/tcp_socket_spec.rb +42 -31
  42. data/spec/nio/selectables/udp_socket_spec.rb +2 -0
  43. data/spec/nio/selector_spec.rb +10 -4
  44. data/spec/spec_helper.rb +24 -3
  45. data/spec/support/selectable_examples.rb +7 -5
  46. data/tasks/extension.rake +2 -0
  47. data/tasks/rspec.rake +2 -0
  48. data/tasks/rubocop.rake +2 -0
  49. metadata +21 -14
  50. data/.rubocop_todo.yml +0 -35
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
5
  RSpec.describe "IO.pipe" do
@@ -6,6 +8,7 @@ RSpec.describe "IO.pipe" do
6
8
  let :unreadable_subject do
7
9
  pair.first
8
10
  end
11
+
9
12
  let :readable_subject do
10
13
  pipe, peer = pair
11
14
  peer << "data"
@@ -15,8 +18,9 @@ RSpec.describe "IO.pipe" do
15
18
  let :writable_subject do
16
19
  pair.last
17
20
  end
21
+
18
22
  let :unwritable_subject do
19
- reader, pipe = IO.pipe
23
+ _reader, pipe = pair
20
24
 
21
25
  # HACK: On OS X 10.8, this str must be larger than PIPE_BUF. Otherwise,
22
26
  # the write is atomic and select() will return writable but write()
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
  require "openssl"
3
5
 
4
- RSpec.describe OpenSSL::SSL::SSLSocket, if: RUBY_VERSION >= "1.9.0" do
5
- let(:tcp_port) { 34_567 }
6
+ RSpec.describe OpenSSL::SSL::SSLSocket do
7
+ let(:addr) { "localhost" }
8
+ let(:port) { next_available_tcp_port }
6
9
 
7
10
  let(:ssl_key) { OpenSSL::PKey::RSA.new(1024) }
8
11
 
@@ -29,8 +32,8 @@ RSpec.describe OpenSSL::SSL::SSLSocket, if: RUBY_VERSION >= "1.9.0" do
29
32
  end
30
33
 
31
34
  let :readable_subject do
32
- server = TCPServer.new("localhost", tcp_port)
33
- client = TCPSocket.open("localhost", tcp_port)
35
+ server = TCPServer.new(addr, port)
36
+ client = TCPSocket.open(addr, port)
34
37
  peer = server.accept
35
38
 
36
39
  ssl_peer = OpenSSL::SSL::SSLSocket.new(peer, ssl_server_context)
@@ -52,8 +55,8 @@ RSpec.describe OpenSSL::SSL::SSLSocket, if: RUBY_VERSION >= "1.9.0" do
52
55
  end
53
56
 
54
57
  let :unreadable_subject do
55
- server = TCPServer.new("localhost", tcp_port + 1)
56
- client = TCPSocket.new("localhost", tcp_port + 1)
58
+ server = TCPServer.new(addr, port)
59
+ client = TCPSocket.new(addr, port)
57
60
  peer = server.accept
58
61
 
59
62
  ssl_peer = OpenSSL::SSL::SSLSocket.new(peer, ssl_server_context)
@@ -72,8 +75,8 @@ RSpec.describe OpenSSL::SSL::SSLSocket, if: RUBY_VERSION >= "1.9.0" do
72
75
  end
73
76
 
74
77
  let :writable_subject do
75
- server = TCPServer.new("localhost", tcp_port + 2)
76
- client = TCPSocket.new("localhost", tcp_port + 2)
78
+ server = TCPServer.new(addr, port)
79
+ client = TCPSocket.new(addr, port)
77
80
  peer = server.accept
78
81
 
79
82
  ssl_peer = OpenSSL::SSL::SSLSocket.new(peer, ssl_server_context)
@@ -92,8 +95,8 @@ RSpec.describe OpenSSL::SSL::SSLSocket, if: RUBY_VERSION >= "1.9.0" do
92
95
  end
93
96
 
94
97
  let :unwritable_subject do
95
- server = TCPServer.new("localhost", tcp_port + 3)
96
- client = TCPSocket.open("localhost", tcp_port + 3)
98
+ server = TCPServer.new(addr, port)
99
+ client = TCPSocket.new(addr, port)
97
100
  peer = server.accept
98
101
 
99
102
  ssl_peer = OpenSSL::SSL::SSLSocket.new(peer, ssl_server_context)
@@ -140,8 +143,8 @@ RSpec.describe OpenSSL::SSL::SSLSocket, if: RUBY_VERSION >= "1.9.0" do
140
143
  let :pair do
141
144
  pending "figure out why newly created sockets are selecting readable immediately"
142
145
 
143
- server = TCPServer.new("localhost", tcp_port + 4)
144
- client = TCPSocket.open("localhost", tcp_port + 4)
146
+ server = TCPServer.new(addr, port)
147
+ client = TCPSocket.new(addr, port)
145
148
  peer = server.accept
146
149
 
147
150
  ssl_peer = OpenSSL::SSL::SSLSocket.new(peer, ssl_server_context)
@@ -1,20 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
5
  RSpec.describe TCPSocket do
4
- port_offset = 0
5
- let(:tcp_port) { 12_345 + (port_offset += 1) }
6
+ let(:addr) { "127.0.0.1" }
7
+ let(:port) { next_available_tcp_port }
6
8
 
7
9
  let :readable_subject do
8
- server = TCPServer.new("localhost", tcp_port)
9
- sock = TCPSocket.open("localhost", tcp_port)
10
+ server = TCPServer.new(addr, port)
11
+ sock = TCPSocket.new(addr, port)
10
12
  peer = server.accept
11
13
  peer << "data"
12
14
  sock
13
15
  end
14
16
 
15
17
  let :unreadable_subject do
16
- TCPServer.new("localhost", tcp_port)
17
- sock = TCPSocket.new("localhost", tcp_port)
18
+ TCPServer.new(addr, port)
19
+ sock = TCPSocket.new(addr, port)
18
20
 
19
21
  # Sanity check to make sure we actually produced an unreadable socket
20
22
  if select([sock], [], [], 0)
@@ -25,21 +27,25 @@ RSpec.describe TCPSocket do
25
27
  end
26
28
 
27
29
  let :writable_subject do
28
- TCPServer.new("localhost", tcp_port)
29
- TCPSocket.new("localhost", tcp_port)
30
+ TCPServer.new(addr, port)
31
+ TCPSocket.new(addr, port)
30
32
  end
31
33
 
32
34
  let :unwritable_subject do
33
- server = TCPServer.new("localhost", tcp_port)
34
- sock = TCPSocket.open("localhost", tcp_port)
35
- peer = server.accept
35
+ server = TCPServer.new(addr, port)
36
+ sock = TCPSocket.new(addr, port)
36
37
 
37
- begin
38
+ # TODO: close this socket
39
+ _peer = server.accept
40
+
41
+ loop do
38
42
  sock.write_nonblock "X" * 1024
39
- _, writers = select [], [sock], [], 0
40
- end while writers && writers.include?(sock)
43
+ _, writers = Kernel.select([], [sock], [], 0)
41
44
 
42
- # I think the kernel might manage to drain its buffer a bit even after
45
+ break unless writers && writers.include?(sock)
46
+ end
47
+
48
+ # HAX: I think the kernel might manage to drain its buffer a bit even after
43
49
  # the socket first goes unwritable. Attempt to sleep past this and then
44
50
  # attempt to write again
45
51
  sleep 0.1
@@ -59,8 +65,8 @@ RSpec.describe TCPSocket do
59
65
  end
60
66
 
61
67
  let :pair do
62
- server = TCPServer.new("localhost", tcp_port)
63
- client = TCPSocket.open("localhost", tcp_port)
68
+ server = TCPServer.new(addr, port)
69
+ client = TCPSocket.new(addr, port)
64
70
  [client, server.accept]
65
71
  end
66
72
 
@@ -69,20 +75,25 @@ RSpec.describe TCPSocket do
69
75
  it_behaves_like "an NIO bidirectional stream"
70
76
 
71
77
  context :connect do
72
- it "selects writable when connected" do
73
- selector = NIO::Selector.new
74
- server = TCPServer.new("127.0.0.1", tcp_port)
75
-
76
- client = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
77
- monitor = selector.register(client, :w)
78
-
79
- expect do
80
- client.connect_nonblock Socket.sockaddr_in(tcp_port, "127.0.0.1")
81
- end.to raise_exception Errno::EINPROGRESS
82
-
83
- expect(selector.select(0.001)).to include monitor
84
- result = client.getsockopt(::Socket::SOL_SOCKET, ::Socket::SO_ERROR)
85
- expect(result.unpack("i").first).to be_zero
78
+ it "selects writable when connected", retry: 5 do # retry: Flaky on OS X
79
+ begin
80
+ server = TCPServer.new(addr, port)
81
+ selector = NIO::Selector.new
82
+
83
+ client = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
84
+ monitor = selector.register(client, :w)
85
+
86
+ expect do
87
+ client.connect_nonblock Socket.sockaddr_in(port, addr)
88
+ end.to raise_exception Errno::EINPROGRESS
89
+
90
+ expect(selector.select(0.001)).to include monitor
91
+ result = client.getsockopt(::Socket::SOL_SOCKET, ::Socket::SO_ERROR)
92
+ expect(result.unpack("i").first).to be_zero
93
+ ensure
94
+ server.close rescue nil
95
+ selector.close rescue nil
96
+ end
86
97
  end
87
98
  end
88
99
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
5
  RSpec.describe UDPSocket do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
  require "timeout"
3
5
 
@@ -11,6 +13,12 @@ RSpec.describe NIO::Selector do
11
13
  let(:reader) { pair.first }
12
14
  let(:writer) { pair.last }
13
15
 
16
+ context "backend" do
17
+ it "knows its backend" do
18
+ expect(subject.backend).to be_a Symbol
19
+ end
20
+ end
21
+
14
22
  context "register" do
15
23
  it "registers IO objects" do
16
24
  monitor = subject.register(reader, :r)
@@ -43,9 +51,7 @@ RSpec.describe NIO::Selector do
43
51
 
44
52
  it "reports if it is empty" do
45
53
  expect(subject).to be_empty
46
-
47
- monitor = subject.register(reader, :r)
48
-
54
+ subject.register(reader, :r)
49
55
  expect(subject).not_to be_empty
50
56
  end
51
57
 
@@ -96,7 +102,7 @@ RSpec.describe NIO::Selector do
96
102
 
97
103
  thread = Thread.new do
98
104
  started_at = Time.now
99
- expect(subject.select).to be_nil
105
+ expect(subject.select).to eq []
100
106
  Time.now - started_at
101
107
  end
102
108
 
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "coveralls"
2
4
  Coveralls.wear!
3
5
 
4
- require "rubygems"
5
- require "bundler/setup"
6
6
  require "nio"
7
7
  require "support/selectable_examples"
8
+ require "rspec/retry"
9
+
10
+ RSpec.configure do |config|
11
+ config.disable_monkey_patching!
12
+ config.verbose_retry = true
13
+ config.display_try_failure_messages = true
14
+ end
15
+
16
+ $current_tcp_port = 10_000
17
+
18
+ def next_available_tcp_port
19
+ loop do
20
+ $current_tcp_port += 1
21
+
22
+ begin
23
+ sock = Timeout.timeout(0.1) { TCPSocket.new("localhost", $current_tcp_port) }
24
+ rescue Errno::ECONNREFUSED
25
+ break $current_tcp_port
26
+ end
8
27
 
9
- RSpec.configure(&:disable_monkey_patching!)
28
+ sock.close
29
+ end
30
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.shared_context "an NIO selectable" do
2
4
  let(:selector) { NIO::Selector.new }
3
5
 
4
- it "selects readable objects" do
6
+ it "selects readable objects", retry: 5 do # retry: Flaky on OS X
5
7
  monitor = selector.register(readable_subject, :r)
6
8
  ready = selector.select(0)
7
9
  expect(ready).to be_an Enumerable
@@ -9,7 +11,7 @@ RSpec.shared_context "an NIO selectable" do
9
11
  end
10
12
 
11
13
  it "does not select unreadable objects" do
12
- monitor = selector.register(unreadable_subject, :r)
14
+ selector.register(unreadable_subject, :r)
13
15
  expect(selector.select(0)).to be_nil
14
16
  end
15
17
 
@@ -21,7 +23,7 @@ RSpec.shared_context "an NIO selectable" do
21
23
  end
22
24
 
23
25
  it "does not select unwritable objects" do
24
- monitor = selector.register(unwritable_subject, :w)
26
+ selector.register(unwritable_subject, :w)
25
27
  expect(selector.select(0)).to be_nil
26
28
  end
27
29
  end
@@ -49,8 +51,8 @@ RSpec.shared_context "an NIO bidirectional stream" do
49
51
  let(:stream) { pair.first }
50
52
  let(:peer) { pair.last }
51
53
 
52
- it "selects readable and writable" do
53
- monitor = selector.register(readable_subject, :rw)
54
+ it "selects readable and writable", retry: 5 do # retry: Flaky on OS X
55
+ selector.register(readable_subject, :rw)
54
56
  selector.select(0) do |m|
55
57
  expect(m.readiness).to eq(:rw)
56
58
  end
data/tasks/extension.rake CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  if defined? JRUBY_VERSION
2
4
  require "rake/javaextensiontask"
3
5
  Rake::JavaExtensionTask.new("nio4r_ext") do |ext|
data/tasks/rspec.rake CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rspec/core/rake_task"
2
4
 
3
5
  RSpec::Core::RakeTask.new
data/tasks/rubocop.rake CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rubocop/rake_task"
2
4
 
3
5
  RuboCop::RakeTask.new
metadata CHANGED
@@ -1,23 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nio4r
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 2.0.0
5
5
  platform: java
6
6
  authors:
7
7
  - Tony Arcieri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-31 00:00:00.000000000 Z
11
+ date: 2016-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
- version_requirements: !ruby/object:Gem::Requirement
15
+ requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
- requirement: !ruby/object:Gem::Requirement
20
+ version_requirements: !ruby/object:Gem::Requirement
21
21
  requirements:
22
22
  - - ">="
23
23
  - !ruby/object:Gem::Version
@@ -26,21 +26,21 @@ dependencies:
26
26
  type: :development
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
- version_requirements: !ruby/object:Gem::Requirement
29
+ requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
- requirement: !ruby/object:Gem::Requirement
34
+ version_requirements: !ruby/object:Gem::Requirement
35
35
  requirements:
36
36
  - - ">="
37
37
  - !ruby/object:Gem::Version
38
38
  version: '0'
39
39
  prerelease: false
40
40
  type: :development
41
- description: New IO for Ruby
41
+ description: Cross-platform asynchronous I/O primitives for scalable network clients and servers. Inspired by the Java NIO API, but simplified for ease-of-use.
42
42
  email:
43
- - tony.arcieri@gmail.com
43
+ - bascule@gmail.com
44
44
  executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
@@ -48,10 +48,11 @@ files:
48
48
  - ".gitignore"
49
49
  - ".rspec"
50
50
  - ".rubocop.yml"
51
- - ".rubocop_todo.yml"
51
+ - ".ruby-version"
52
52
  - ".travis.yml"
53
53
  - CHANGES.md
54
54
  - Gemfile
55
+ - Guardfile
55
56
  - LICENSE.txt
56
57
  - README.md
57
58
  - Rakefile
@@ -71,14 +72,19 @@ files:
71
72
  - ext/libev/ev_win32.c
72
73
  - ext/libev/ev_wrap.h
73
74
  - ext/libev/test_libev_win32.c
75
+ - ext/nio4r/bytebuffer.c
74
76
  - ext/nio4r/extconf.rb
75
77
  - ext/nio4r/libev.h
76
78
  - ext/nio4r/monitor.c
77
79
  - ext/nio4r/nio4r.h
78
80
  - ext/nio4r/nio4r_ext.c
81
+ - ext/nio4r/org/nio4r/ByteBuffer.java
82
+ - ext/nio4r/org/nio4r/Monitor.java
79
83
  - ext/nio4r/org/nio4r/Nio4r.java
84
+ - ext/nio4r/org/nio4r/Selector.java
80
85
  - ext/nio4r/selector.c
81
86
  - lib/nio.rb
87
+ - lib/nio/bytebuffer.rb
82
88
  - lib/nio/monitor.rb
83
89
  - lib/nio/selector.rb
84
90
  - lib/nio/version.rb
@@ -86,6 +92,7 @@ files:
86
92
  - logo.png
87
93
  - nio4r.gemspec
88
94
  - spec/nio/acceptables_spec.rb
95
+ - spec/nio/bytebuffer_spec.rb
89
96
  - spec/nio/monitor_spec.rb
90
97
  - spec/nio/selectables/pipe_spec.rb
91
98
  - spec/nio/selectables/ssl_socket_spec.rb
@@ -97,7 +104,7 @@ files:
97
104
  - tasks/extension.rake
98
105
  - tasks/rspec.rake
99
106
  - tasks/rubocop.rake
100
- homepage: https://github.com/celluloid/nio4r
107
+ homepage: https://github.com/socketry/nio4r
101
108
  licenses:
102
109
  - MIT
103
110
  metadata: {}
@@ -109,7 +116,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
109
116
  requirements:
110
117
  - - ">="
111
118
  - !ruby/object:Gem::Version
112
- version: '0'
119
+ version: 2.2.2
113
120
  required_rubygems_version: !ruby/object:Gem::Requirement
114
121
  requirements:
115
122
  - - ">="
@@ -117,12 +124,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
124
  version: '0'
118
125
  requirements: []
119
126
  rubyforge_project:
120
- rubygems_version: 2.4.8
127
+ rubygems_version: 2.6.8
121
128
  signing_key:
122
129
  specification_version: 4
123
- summary: NIO provides a high performance selector API for monitoring IO objects
130
+ summary: New IO for Ruby
124
131
  test_files:
125
132
  - spec/nio/acceptables_spec.rb
133
+ - spec/nio/bytebuffer_spec.rb
126
134
  - spec/nio/monitor_spec.rb
127
135
  - spec/nio/selectables/pipe_spec.rb
128
136
  - spec/nio/selectables/ssl_socket_spec.rb
@@ -131,4 +139,3 @@ test_files:
131
139
  - spec/nio/selector_spec.rb
132
140
  - spec/spec_helper.rb
133
141
  - spec/support/selectable_examples.rb
134
- has_rdoc: