libuv 2.0.12 → 3.0.0

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +67 -34
  4. data/lib/libuv.rb +30 -5
  5. data/lib/libuv/async.rb +16 -10
  6. data/lib/libuv/check.rb +19 -12
  7. data/lib/libuv/coroutines.rb +39 -12
  8. data/lib/libuv/dns.rb +25 -18
  9. data/lib/libuv/error.rb +2 -0
  10. data/lib/libuv/ext/ext.rb +28 -36
  11. data/lib/libuv/ext/platform/darwin_x64.rb +2 -0
  12. data/lib/libuv/ext/platform/unix.rb +2 -0
  13. data/lib/libuv/ext/platform/windows.rb +2 -0
  14. data/lib/libuv/ext/tasks.rb +2 -0
  15. data/lib/libuv/ext/tasks/mac.rb +2 -0
  16. data/lib/libuv/ext/tasks/unix.rb +2 -0
  17. data/lib/libuv/ext/tasks/win.rb +2 -0
  18. data/lib/libuv/ext/types.rb +2 -1
  19. data/lib/libuv/file.rb +67 -50
  20. data/lib/libuv/filesystem.rb +63 -61
  21. data/lib/libuv/fs_event.rb +7 -4
  22. data/lib/libuv/handle.rb +30 -14
  23. data/lib/libuv/idle.rb +17 -10
  24. data/lib/libuv/mixins/accessors.rb +41 -0
  25. data/lib/libuv/mixins/assertions.rb +3 -1
  26. data/lib/libuv/mixins/fs_checks.rb +29 -6
  27. data/lib/libuv/mixins/listener.rb +4 -2
  28. data/lib/libuv/mixins/net.rb +4 -2
  29. data/lib/libuv/mixins/resource.rb +5 -3
  30. data/lib/libuv/mixins/stream.rb +128 -35
  31. data/lib/libuv/pipe.rb +54 -27
  32. data/lib/libuv/prepare.rb +19 -12
  33. data/lib/libuv/q.rb +109 -101
  34. data/lib/libuv/{loop.rb → reactor.rb} +163 -85
  35. data/lib/libuv/signal.rb +13 -5
  36. data/lib/libuv/tcp.rb +109 -63
  37. data/lib/libuv/timer.rb +44 -24
  38. data/lib/libuv/tty.rb +8 -3
  39. data/lib/libuv/udp.rb +49 -22
  40. data/lib/libuv/version.rb +3 -1
  41. data/lib/libuv/work.rb +14 -10
  42. data/libuv.gemspec +11 -9
  43. data/spec/async_spec.rb +13 -13
  44. data/spec/coroutines_spec.rb +20 -50
  45. data/spec/defer_spec.rb +182 -311
  46. data/spec/dns_spec.rb +51 -41
  47. data/spec/dsl_spec.rb +43 -0
  48. data/spec/filesystem_spec.rb +65 -87
  49. data/spec/idle_spec.rb +19 -33
  50. data/spec/pipe_spec.rb +25 -32
  51. data/spec/tcp_spec.rb +116 -53
  52. data/spec/timer_spec.rb +3 -3
  53. data/spec/udp_spec.rb +16 -17
  54. data/spec/zen_spec.rb +2 -3
  55. metadata +37 -30
data/spec/idle_spec.rb CHANGED
@@ -6,48 +6,34 @@ describe Libuv::Idle do
6
6
  @log = []
7
7
  @general_failure = []
8
8
 
9
- @loop = Libuv::Loop.default
10
- @server = @loop.pipe
11
- @client = @loop.pipe
12
- @timeout = @loop.timer do
13
- @loop.stop
14
- @general_failure << "test timed out"
15
- end
16
- @timeout.start(5000)
17
-
18
- @loop.all(@server, @client, @timeout).catch do |reason|
19
- @general_failure << reason.inspect
20
- p "Failed with: #{reason.message}\n#{reason.backtrace.join("\n")}\n"
9
+ @reactor = Libuv::Reactor.default
10
+ @reactor.notifier do |error, context|
11
+ begin
12
+ @general_failure << "Log called: #{context}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
13
+ rescue Exception => e
14
+ @general_failure << "error in logger #{e.inspect}"
15
+ end
21
16
  end
17
+ @timeout = @reactor.timer {
18
+ @reactor.stop
19
+ @general_failure << "test timed out"
20
+ }.start(5000)
22
21
  end
23
22
 
24
23
  it "should increase the idle count when there is nothing to process" do
25
- @loop.run { |logger|
26
- logger.progress do |level, errorid, error|
27
- begin
28
- p "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
29
- rescue Exception
30
- p 'error in logger'
31
- end
32
- end
33
-
24
+ @reactor.run { |reactor|
34
25
  @idle_calls = 0
35
26
 
36
- idle = @loop.idle do |e|
27
+ idle = @reactor.idle { |e|
37
28
  @idle_calls += 1
38
- end
39
- idle.start
29
+ }.start
40
30
 
41
- timer = @loop.timer proc {}
42
- timer.start(1, 0)
43
-
44
- stopper = @loop.timer do
45
- idle.close
46
- timer.close
31
+ stopper = @reactor.timer {
32
+ idle.stop.close
47
33
  stopper.close
48
- @loop.stop
49
- end
50
- stopper.start(1000, 0)
34
+ @timeout.close
35
+ @reactor.stop
36
+ }.start(1000)
51
37
  }
52
38
 
53
39
  expect(@general_failure).to eq([])
data/spec/pipe_spec.rb CHANGED
@@ -6,22 +6,30 @@ describe Libuv::Pipe do
6
6
  @log = []
7
7
  @general_failure = []
8
8
 
9
- @loop = Libuv::Loop.new
10
- @server = @loop.pipe
11
- @client = @loop.pipe
12
- @timeout = @loop.timer do
13
- @loop.stop
9
+ @reactor = Libuv::Reactor.new
10
+ @server = @reactor.pipe
11
+ @client = @reactor.pipe
12
+ @timeout = @reactor.timer do
13
+ @reactor.stop
14
14
  @general_failure << "test timed out"
15
15
  end
16
16
  @timeout.start(5000)
17
17
 
18
18
  @pipefile = "/tmp/test-pipes.pipe"
19
19
 
20
- @loop.all(@server, @client, @timeout).catch do |reason|
20
+ @reactor.all(@server, @client, @timeout).catch do |reason|
21
21
  @general_failure << reason.inspect
22
22
  @general_failure << "Failed with: #{reason.message}\n#{reason.backtrace}\n"
23
23
  end
24
24
 
25
+ @reactor.notifier do |error, context|
26
+ begin
27
+ @general_failure << "Log called: #{context}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
28
+ rescue Exception => e
29
+ @general_failure << "error in logger #{e.inspect}"
30
+ end
31
+ end
32
+
25
33
  begin
26
34
  File.unlink(@pipefile)
27
35
  rescue
@@ -38,15 +46,7 @@ describe Libuv::Pipe do
38
46
  describe 'bidirectional inter process communication' do
39
47
 
40
48
  it "should send a ping and return a pong" do
41
- @loop.run { |logger|
42
- logger.progress do |level, errorid, error|
43
- begin
44
- @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace}\n"
45
- rescue Exception
46
- @general_failure << 'error in logger'
47
- end
48
- end
49
-
49
+ @reactor.run { |reactor|
50
50
  @server.bind(@pipefile) do |client|
51
51
  client.progress do |data|
52
52
  @log << data
@@ -58,7 +58,7 @@ describe Libuv::Pipe do
58
58
  # catch server errors
59
59
  @server.catch do |reason|
60
60
  @general_failure << reason.inspect
61
- @loop.stop
61
+ @reactor.stop
62
62
 
63
63
  @general_failure << "Failed with: #{reason.message}\n#{reason.backtrace}\n"
64
64
  end
@@ -82,15 +82,15 @@ describe Libuv::Pipe do
82
82
 
83
83
  @client.catch do |reason|
84
84
  @general_failure << reason.inspect
85
- @loop.stop
85
+ @reactor.stop
86
86
 
87
87
  @general_failure << "Failed with: #{reason.message}\n#{reason.backtrace}\n"
88
88
  end
89
89
 
90
- # Stop the loop once the client handle is closed
90
+ # Stop the reactor once the client handle is closed
91
91
  @client.finally do
92
92
  @server.close
93
- @loop.stop
93
+ @reactor.stop
94
94
  end
95
95
  }
96
96
 
@@ -106,15 +106,9 @@ describe Libuv::Pipe do
106
106
  end
107
107
 
108
108
  it "should send work to a consumer" do
109
- @loop.run { |logger|
110
- logger.progress do |level, errorid, error|
111
- @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
112
- end
113
-
114
-
115
- heartbeat = @loop.timer
116
- @file1 = @loop.file(@pipefile, File::RDWR|File::NONBLOCK)
117
- @file1.progress do
109
+ @reactor.run { |reactor|
110
+ heartbeat = @reactor.timer
111
+ @file1 = @reactor.file(@pipefile, File::RDWR|File::NONBLOCK) do
118
112
  @server.open(@file1.fileno) do |server|
119
113
  heartbeat.progress do
120
114
  @server.write('workload').catch do |err|
@@ -128,8 +122,7 @@ describe Libuv::Pipe do
128
122
  @general_failure << "Log called: #{e.inspect} - #{e.message}\n"
129
123
  end
130
124
 
131
- @file2 = @loop.file(@pipefile, File::RDWR|File::NONBLOCK)
132
- @file2.progress do
125
+ @file2 = @reactor.file(@pipefile, File::RDWR|File::NONBLOCK) do
133
126
  # connect client to server
134
127
  @client.open(@file2.fileno) do |consumer|
135
128
  consumer.progress do |data|
@@ -141,12 +134,12 @@ describe Libuv::Pipe do
141
134
  end
142
135
 
143
136
 
144
- timeout = @loop.timer do
137
+ timeout = @reactor.timer do
145
138
  @server.close
146
139
  @client.close
147
140
  timeout.close
148
141
  heartbeat.close
149
- @loop.stop
142
+ @reactor.stop
150
143
  end
151
144
  timeout.start(1000)
152
145
  }
data/spec/tcp_spec.rb CHANGED
@@ -7,22 +7,29 @@ describe Libuv::TCP do
7
7
  @log = []
8
8
  @general_failure = []
9
9
 
10
- @loop = Libuv::Loop.new
11
- @server = @loop.tcp
12
- @client = @loop.tcp
13
- @timeout = @loop.timer do
14
- @loop.stop
15
- @loop2.stop if @loop2
10
+ @reactor = Libuv::Reactor.new
11
+ @server = @reactor.tcp
12
+ @client = @reactor.tcp
13
+ @timeout = @reactor.timer do
14
+ @reactor.stop
15
+ @reactor2.stop if @reactor2
16
16
  @general_failure << "test timed out"
17
17
  end
18
18
  @timeout.start(5000)
19
19
 
20
- @loop.all(@server, @client, @timeout).catch do |reason|
20
+ @reactor.all(@server, @client, @timeout).catch do |reason|
21
21
  @general_failure << reason.inspect
22
22
  end
23
23
 
24
24
 
25
25
  @pipefile = "/tmp/test-pipe.pipe"
26
+ @reactor.notifier do |error, context|
27
+ begin
28
+ @general_failure << "Log called: #{context}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
29
+ rescue Exception => e
30
+ @general_failure << "error in logger #{e.inspect}"
31
+ end
32
+ end
26
33
 
27
34
  begin
28
35
  File.unlink(@pipefile)
@@ -32,16 +39,7 @@ describe Libuv::TCP do
32
39
 
33
40
  describe 'basic client server' do
34
41
  it "should send a ping and return a pong", :network => true do
35
- @loop.run { |logger|
36
- logger.progress do |level, errorid, error|
37
- begin
38
- @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
39
- rescue Exception => e
40
- @general_failure << "error in logger #{e.inspect}"
41
- end
42
- end
43
-
44
-
42
+ @reactor.run { |reactor|
45
43
  @server.bind('127.0.0.1', 34567) do |client|
46
44
  client.progress do |data|
47
45
  @log << data
@@ -81,28 +79,103 @@ describe Libuv::TCP do
81
79
  # close the handle
82
80
  @client.finally do
83
81
  @server.close
84
- @loop.stop
82
+ @reactor.stop
85
83
  end
86
84
  }
87
85
 
88
86
  expect(@general_failure).to eq([])
89
87
  expect(@log).to eq(['ping', 'pong'])
90
88
  end
91
- end
92
89
 
93
- it "should handle requests on different threads", :network => true do
94
- @sync = Mutex.new
90
+ it "should work with coroutines", :network => true do
91
+ @reactor.run { |reactor|
92
+ @server.bind('127.0.0.1', 34567) do |client|
93
+ client.progress do |data|
94
+ @log << data
95
95
 
96
- @loop.run { |logger|
97
- logger.progress do |level, errorid, error|
98
- begin
99
- @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
100
- rescue Exception
101
- @general_failure << "error in logger #{e.inspect}"
96
+ client.write('pong')
97
+ end
98
+ client.start_read
99
+ end
100
+
101
+ # catch errors
102
+ @server.catch do |reason|
103
+ @general_failure << reason.inspect
104
+ end
105
+
106
+ # start listening
107
+ @server.listen(1024)
108
+
109
+ # connect client to server
110
+ @client.progress do |data|
111
+ @log << data
112
+
113
+ addrinfo = @reactor.lookup('127.0.0.1')
114
+ @log << addrinfo[0][0]
115
+
116
+ @client.shutdown
117
+ end
118
+ # catch errors
119
+ @client.catch do |reason|
120
+ @general_failure << reason.inspect
102
121
  end
103
- end
104
122
 
123
+ # close the handle
124
+ @client.finally do
125
+ @server.close
126
+ @reactor.stop
127
+ end
128
+ @client.connect('127.0.0.1', 34567)
129
+ @client.start_read
130
+ @client.write('ping')
131
+ }
105
132
 
133
+ expect(@general_failure).to eq([])
134
+ expect(@log).to eq(['ping', 'pong', '127.0.0.1'])
135
+ end
136
+
137
+ it "should quack a bit like an IO object", :network => true do
138
+ @reactor.run { |reactor|
139
+ @server.bind('127.0.0.1', 34567) do |client|
140
+ @log << client.read(4)
141
+ client.write('pong')
142
+ end
143
+
144
+ # catch errors
145
+ @server.catch do |reason|
146
+ @general_failure << reason.inspect
147
+ end
148
+
149
+ # start listening
150
+ @server.listen(1024)
151
+
152
+ # catch errors
153
+ @client.catch do |reason|
154
+ @general_failure << reason.inspect
155
+ end
156
+
157
+ # close the handle
158
+ @client.finally do
159
+ @server.close
160
+ @reactor.stop
161
+ end
162
+ @client.connect('127.0.0.1', 34567)
163
+ @client.write('ping')
164
+ @log << @client.read(4)
165
+ addrinfo = @reactor.lookup('127.0.0.1')
166
+ @log << addrinfo[0][0]
167
+ @client.shutdown
168
+ }
169
+
170
+ expect(@general_failure).to eq([])
171
+ expect(@log).to eq(['ping', 'pong', '127.0.0.1'])
172
+ end
173
+ end
174
+
175
+ it "should handle requests on different threads", :network => true do
176
+ @sync = Mutex.new
177
+
178
+ @reactor.run { |reactor|
106
179
  @remote = nil
107
180
  @server.bind('127.0.0.1', 45678) do |client|
108
181
  @remote.write2(client)
@@ -114,7 +187,7 @@ describe Libuv::TCP do
114
187
  end
115
188
 
116
189
 
117
- @pipeserve = @loop.pipe(true)
190
+ @pipeserve = @reactor.pipe(true)
118
191
  @pipeserve.bind(@pipefile) do |client|
119
192
  @remote = client
120
193
 
@@ -156,19 +229,18 @@ describe Libuv::TCP do
156
229
 
157
230
 
158
231
  Thread.new do
159
- @loop2 = Libuv::Loop.new
160
- @pipeclient = @loop2.pipe(true)
232
+ @reactor2 = Libuv::Reactor.new
233
+ @reactor2.notifier do |error, context|
234
+ begin
235
+ @general_failure << "Log called: #{context}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
236
+ rescue Exception
237
+ @general_failure << "error in logger #{e.inspect}"
238
+ end
239
+ end
240
+ @pipeclient = @reactor2.pipe(true)
161
241
 
162
242
 
163
- @loop2.run do |logger|
164
- logger.progress do |level, errorid, error|
165
- begin
166
- @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
167
- rescue Exception
168
- @general_failure << "error in logger #{e.inspect}"
169
- end
170
- end
171
-
243
+ @reactor2.run do |reactor|
172
244
  # connect client to server
173
245
  @pipeclient.connect(@pipefile) do |client|
174
246
  @pipeclient.progress do |data|
@@ -183,8 +255,8 @@ describe Libuv::TCP do
183
255
  connection.start_read
184
256
  connection.finally do
185
257
  @pipeclient.close
186
- @loop2.stop
187
- @loop.stop
258
+ @reactor2.stop
259
+ @reactor.stop
188
260
  end
189
261
  end
190
262
 
@@ -200,16 +272,7 @@ describe Libuv::TCP do
200
272
 
201
273
  describe 'basic TLS client and server' do
202
274
  it "should send a ping and return a pong", :network => true do
203
- @loop.run { |logger|
204
- logger.progress do |level, errorid, error|
205
- begin
206
- @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
207
- rescue Exception
208
- @general_failure << "error in logger #{e.inspect}"
209
- end
210
- end
211
-
212
-
275
+ @reactor.run { |reactor|
213
276
  @server.bind('127.0.0.1', 56789) do |client|
214
277
  client.start_tls(server: true)
215
278
  client.progress do |data|
@@ -251,7 +314,7 @@ describe Libuv::TCP do
251
314
  # close the handle
252
315
  @client.finally do
253
316
  @server.close
254
- @loop.stop
317
+ @reactor.stop
255
318
  end
256
319
  }
257
320
 
data/spec/timer_spec.rb CHANGED
@@ -3,9 +3,9 @@ require 'libuv'
3
3
  describe Libuv::Timer do
4
4
  describe 'setting properties' do
5
5
  it "should allow repeat to be set" do
6
- @loop = Libuv::Loop.new
7
- @loop.run { |logger|
8
- @timer = @loop.timer
6
+ @reactor = Libuv::Reactor.new
7
+ @reactor.run { |logger|
8
+ @timer = @reactor.timer
9
9
  @timer.repeat = 5
10
10
  expect(@timer.repeat).to eq(5)
11
11
  }
data/spec/udp_spec.rb CHANGED
@@ -7,32 +7,31 @@ describe Libuv::UDP do
7
7
  @log = []
8
8
  @general_failure = []
9
9
 
10
- @loop = Libuv::Loop.new
11
- @server = @loop.udp
12
- @client = @loop.udp
13
- @timeout = @loop.timer do
14
- @loop.stop
10
+ @reactor = Libuv::Reactor.new
11
+ @server = @reactor.udp
12
+ @client = @reactor.udp
13
+ @timeout = @reactor.timer do
14
+ @reactor.stop
15
15
  @general_failure << "test timed out"
16
16
  end
17
17
  @timeout.start(5000)
18
18
 
19
- @loop.all(@server, @client, @timeout).catch do |reason|
19
+ @reactor.notifier do |error, context|
20
+ begin
21
+ @general_failure << "Log called: #{context}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
22
+ rescue Exception => e
23
+ @general_failure << "error in logger #{e.inspect}"
24
+ end
25
+ end
26
+
27
+ @reactor.all(@server, @client, @timeout).catch do |reason|
20
28
  @general_failure << reason.inspect
21
29
  end
22
30
  end
23
31
 
24
32
  describe 'basic client server' do
25
33
  it "should send a ping and return a pong", :network => true do
26
- @loop.run { |logger|
27
- logger.progress do |level, errorid, error|
28
- begin
29
- @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
30
- rescue Exception => e
31
- @general_failure << "error in logger #{e.inspect}"
32
- end
33
- end
34
-
35
-
34
+ @reactor.run { |reactor|
36
35
  @server.bind('127.0.0.1', 34567)
37
36
  @server.progress do |data, ip, port, server|
38
37
  @log << data
@@ -63,7 +62,7 @@ describe Libuv::UDP do
63
62
  # close the handle
64
63
  @client.finally do
65
64
  @server.close
66
- @loop.stop
65
+ @reactor.stop
67
66
  end
68
67
  }
69
68