nio4r 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
data/lib/nio.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'thread'
2
+ require 'nio/version'
3
+
4
+ # New I/O for Ruby
5
+ module NIO
6
+ # NIO implementation, one of the following (as a string):
7
+ # * select: in pure Ruby using Kernel.select
8
+ # * libev: as a C extension using libev
9
+ # * java: using Java NIO
10
+ def self.engine; ENGINE end
11
+ end
12
+
13
+ if ENV["NIO4R_PURE"]
14
+ require 'nio/monitor'
15
+ require 'nio/selector'
16
+ NIO::ENGINE = 'select'
17
+ else
18
+ if defined?(JRUBY_VERSION)
19
+ require 'java'
20
+ require 'nio/jruby/monitor'
21
+ require 'nio/jruby/selector'
22
+ NIO::ENGINE = 'java'
23
+ else
24
+ require 'nio4r_ext'
25
+ NIO::ENGINE = 'libev'
26
+ end
27
+ end
28
+
29
+ # TIMTOWTDI!!!
30
+ Nio = NIO
data/nio4r.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/nio/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Tony Arcieri"]
6
+ gem.email = ["tony.arcieri@gmail.com"]
7
+ gem.description = "New IO for Ruby"
8
+ gem.summary = "NIO provides a high performance selector API for monitoring IO objects"
9
+ gem.homepage = "https://github.com/tarcieri/nio4r"
10
+ gem.platform = "java"
11
+
12
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
13
+ gem.files = `git ls-files`.split("\n")
14
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ gem.name = "nio4r"
16
+ gem.require_paths = ["lib"]
17
+ gem.version = NIO::VERSION
18
+ #gem.extensions = ["ext/nio4r/extconf.rb"]
19
+
20
+ gem.add_development_dependency "rake-compiler", "~> 0.7.9"
21
+ gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "rspec", ">= 2.7.0"
23
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe NIO::Monitor do
4
+ let :readable_pipe do
5
+ pipe, peer = IO.pipe
6
+ peer << "data"
7
+ pipe
8
+ end
9
+
10
+ # let :unreadable_pipe do
11
+ # pipe, _ = IO.pipe
12
+ # pipe
13
+ # end
14
+
15
+ let :selector do
16
+ NIO::Selector.new
17
+ end
18
+
19
+ # Monitors are created by registering IO objects or channels with a selector
20
+ subject { selector.register(readable_pipe, :r) }
21
+
22
+ it "knows its interests" do
23
+ subject.interests.should == :r
24
+ end
25
+
26
+ it "stores arbitrary values" do
27
+ subject.value = 42
28
+ subject.value.should == 42
29
+ end
30
+
31
+ it "closes" do
32
+ subject.should_not be_closed
33
+ subject.close
34
+ subject.should be_closed
35
+ end
36
+ end
@@ -0,0 +1,197 @@
1
+ require 'spec_helper'
2
+
3
+ # Timeouts should be at least this precise (in seconds) to pass the tests
4
+ # Typical precision should be better than this, but if it's worse it will fail
5
+ # the tests
6
+ TIMEOUT_PRECISION = 0.1
7
+
8
+ describe NIO::Selector do
9
+ it "monitors IO objects" do
10
+ pipe, _ = IO.pipe
11
+
12
+ monitor = subject.register(pipe, :r)
13
+ monitor.should_not be_closed
14
+ end
15
+
16
+ it "knows which IO objects are registered" do
17
+ reader, writer = IO.pipe
18
+ subject.register(reader, :r)
19
+
20
+ subject.should be_registered(reader)
21
+ subject.should_not be_registered(writer)
22
+ end
23
+
24
+ it "deregisters IO objects" do
25
+ pipe, _ = IO.pipe
26
+
27
+ subject.register(pipe, :r)
28
+ monitor = subject.deregister(pipe)
29
+ subject.should_not be_registered(pipe)
30
+ monitor.should be_closed
31
+ end
32
+
33
+ context "select" do
34
+ it "waits for a timeout when selecting" do
35
+ reader, writer = IO.pipe
36
+ monitor = subject.register(reader, :r)
37
+
38
+ payload = "hi there"
39
+ writer << payload
40
+
41
+ timeout = 0.5
42
+ started_at = Time.now
43
+ subject.select(timeout).should include monitor
44
+ (Time.now - started_at).should be_within(TIMEOUT_PRECISION).of(0)
45
+ reader.read_nonblock(payload.size)
46
+
47
+ started_at = Time.now
48
+ subject.select(timeout).should be_nil
49
+ (Time.now - started_at).should be_within(TIMEOUT_PRECISION).of(timeout)
50
+ end
51
+
52
+ it "wakes up if signaled to from another thread" do
53
+ pipe, _ = IO.pipe
54
+ subject.register(pipe, :r)
55
+
56
+ thread = Thread.new do
57
+ started_at = Time.now
58
+ subject.select.should be_nil
59
+ Time.now - started_at
60
+ end
61
+
62
+ timeout = 0.1
63
+ sleep timeout
64
+ subject.wakeup
65
+
66
+ thread.value.should be_within(TIMEOUT_PRECISION).of(timeout)
67
+ end
68
+ end
69
+
70
+ it "closes" do
71
+ subject.close
72
+ subject.should be_closed
73
+ end
74
+
75
+ context "selectables" do
76
+ shared_context "an NIO selectable" do
77
+ it "selects for read readiness" do
78
+ waiting_monitor = subject.register(unreadable_subject, :r)
79
+ ready_monitor = subject.register(readable_subject, :r)
80
+
81
+ ready_monitors = subject.select
82
+ ready_monitors.should include ready_monitor
83
+ ready_monitors.should_not include waiting_monitor
84
+ end
85
+
86
+ it "selects for write readiness" do
87
+ waiting_monitor = subject.register(unwritable_subject, :w)
88
+ ready_monitor = subject.register(writable_subject, :w)
89
+
90
+ ready_monitors = subject.select(0.1)
91
+
92
+ ready_monitors.should include ready_monitor
93
+ ready_monitors.should_not include waiting_monitor
94
+ end
95
+ end
96
+
97
+ context "IO.pipe" do
98
+ let :readable_subject do
99
+ pipe, peer = IO.pipe
100
+ peer << "data"
101
+ pipe
102
+ end
103
+
104
+ let :unreadable_subject do
105
+ pipe, _ = IO.pipe
106
+ pipe
107
+ end
108
+
109
+ let :writable_subject do
110
+ _, pipe = IO.pipe
111
+ pipe
112
+ end
113
+
114
+ let :unwritable_subject do
115
+ reader, pipe = IO.pipe
116
+
117
+ begin
118
+ pipe.write_nonblock "JUNK IN THE TUBES"
119
+ _, writers = select [], [pipe], [], 0
120
+ rescue Errno::EPIPE
121
+ break
122
+ end while writers and writers.include? pipe
123
+
124
+ pipe
125
+ end
126
+
127
+ it_behaves_like "an NIO selectable"
128
+ end
129
+
130
+ context TCPSocket do
131
+ let(:tcp_port) { 12345 }
132
+
133
+ let :readable_subject do
134
+ server = TCPServer.new("localhost", tcp_port)
135
+ sock = TCPSocket.open("localhost", tcp_port)
136
+ peer = server.accept
137
+ peer << "data"
138
+ sock
139
+ end
140
+
141
+ let :unreadable_subject do
142
+ TCPServer.new("localhost", tcp_port + 1)
143
+ TCPSocket.open("localhost", tcp_port + 1)
144
+ end
145
+
146
+ let :writable_subject do
147
+ TCPServer.new("localhost", tcp_port + 2)
148
+ TCPSocket.open("localhost", tcp_port + 2)
149
+ end
150
+
151
+ let :unwritable_subject do
152
+ server = TCPServer.new("localhost", tcp_port + 3)
153
+ sock = TCPSocket.open("localhost", tcp_port + 3)
154
+ peer = server.accept
155
+
156
+ begin
157
+ sock.write_nonblock "JUNK IN THE TUBES"
158
+ _, writers = select [], [sock], [], 0
159
+ end while writers and writers.include? sock
160
+
161
+ sock
162
+ end
163
+
164
+ it_behaves_like "an NIO selectable"
165
+ end
166
+
167
+ context UDPSocket do
168
+ let(:udp_port) { 23456 }
169
+
170
+ let :readable_subject do
171
+ sock = UDPSocket.new
172
+ sock.bind('localhost', udp_port)
173
+
174
+ peer = UDPSocket.new
175
+ peer.send("hi there", 0, 'localhost', udp_port)
176
+
177
+ sock
178
+ end
179
+
180
+ let :unreadable_subject do
181
+ sock = UDPSocket.new
182
+ sock.bind('localhost', udp_port + 1)
183
+ sock
184
+ end
185
+
186
+ let :writable_subject do
187
+ pending "come up with a writable UDPSocket example"
188
+ end
189
+
190
+ let :unwritable_subject do
191
+ pending "come up with a UDPSocket that's blocked on writing"
192
+ end
193
+
194
+ it_behaves_like "an NIO selectable"
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'nio'
@@ -0,0 +1,10 @@
1
+ require 'rake/extensiontask'
2
+
3
+ if defined?(JRUBY_VERSION)
4
+ # Don't build the native extension on JRuby since it uses native Java NIO
5
+ task :compile
6
+ else
7
+ Rake::ExtensionTask.new('nio4r_ext') do |ext|
8
+ ext.ext_dir = 'ext/nio4r'
9
+ end
10
+ end
data/tasks/rspec.rake ADDED
@@ -0,0 +1,7 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new
4
+
5
+ RSpec::Core::RakeTask.new(:rcov) do |task|
6
+ task.rcov = true
7
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nio4r
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: java
7
+ authors:
8
+ - Tony Arcieri
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake-compiler
16
+ requirement: &70326293926580 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.7.9
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70326293926580
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &70326293925820 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70326293925820
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70326293924680 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 2.7.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70326293924680
47
+ description: New IO for Ruby
48
+ email:
49
+ - tony.arcieri@gmail.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - .rspec
56
+ - .travis.yml
57
+ - Gemfile
58
+ - LICENSE.txt
59
+ - README.md
60
+ - Rakefile
61
+ - ext/libev/Changes
62
+ - ext/libev/LICENSE
63
+ - ext/libev/README
64
+ - ext/libev/README.embed
65
+ - ext/libev/ev.c
66
+ - ext/libev/ev.h
67
+ - ext/libev/ev_epoll.c
68
+ - ext/libev/ev_kqueue.c
69
+ - ext/libev/ev_poll.c
70
+ - ext/libev/ev_port.c
71
+ - ext/libev/ev_select.c
72
+ - ext/libev/ev_vars.h
73
+ - ext/libev/ev_win32.c
74
+ - ext/libev/ev_wrap.h
75
+ - ext/libev/test_libev_win32.c
76
+ - ext/nio4r/extconf.rb
77
+ - ext/nio4r/libev.h
78
+ - ext/nio4r/monitor.c
79
+ - ext/nio4r/nio4r.h
80
+ - ext/nio4r/nio4r_ext.c
81
+ - ext/nio4r/selector.c
82
+ - lib/nio.rb
83
+ - lib/nio/jruby/monitor.rb
84
+ - lib/nio/jruby/selector.rb
85
+ - lib/nio/monitor.rb
86
+ - lib/nio/selector.rb
87
+ - lib/nio/version.rb
88
+ - nio4r.gemspec
89
+ - spec/nio/monitor_spec.rb
90
+ - spec/nio/selector_spec.rb
91
+ - spec/spec_helper.rb
92
+ - tasks/extension.rake
93
+ - tasks/rspec.rake
94
+ homepage: https://github.com/tarcieri/nio4r
95
+ licenses: []
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 1.8.10
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: NIO provides a high performance selector API for monitoring IO objects
118
+ test_files:
119
+ - spec/nio/monitor_spec.rb
120
+ - spec/nio/selector_spec.rb
121
+ - spec/spec_helper.rb