eventmachine-maglev- 1.0.0.beta.4 → 1.0.0.rc.4
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.
- data/README.md +1 -1
- data/Rakefile +11 -11
- data/eventmachine.gemspec +1 -1
- data/ext/cmain.cpp +41 -3
- data/ext/ed.cpp +31 -6
- data/ext/ed.h +9 -5
- data/ext/em.cpp +33 -10
- data/ext/em.h +11 -1
- data/ext/eventmachine.h +4 -0
- data/ext/extconf.rb +24 -5
- data/ext/fastfilereader/extconf.rb +20 -2
- data/ext/pipe.cpp +2 -2
- data/ext/project.h +3 -2
- data/ext/rubymain.cpp +108 -19
- data/ext/ssl.cpp +9 -1
- data/java/src/com/rubyeventmachine/EmReactor.java +4 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +1 -0
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +6 -0
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +6 -0
- data/lib/em/completion.rb +4 -3
- data/lib/em/connection.rb +17 -2
- data/lib/em/iterator.rb +42 -42
- data/lib/em/pool.rb +7 -2
- data/lib/em/protocols/postgres3.rb +6 -8
- data/lib/em/protocols/smtpclient.rb +28 -28
- data/lib/em/pure_ruby.rb +12 -0
- data/lib/em/threaded_resource.rb +1 -1
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +57 -11
- data/lib/jeventmachine.rb +5 -0
- data/{tasks → rakelib}/cpp.rake_example +0 -0
- data/{tasks → rakelib}/package.rake +0 -0
- data/{tasks → rakelib}/test.rake +0 -0
- data/tests/test_basic.rb +67 -0
- data/tests/test_idle_connection.rb +23 -0
- data/tests/test_pool.rb +67 -1
- data/tests/test_processes.rb +18 -0
- data/tests/test_proxy_connection.rb +13 -1
- data/tests/test_set_sock_opt.rb +37 -0
- data/tests/test_unbind_reason.rb +19 -2
- metadata +15 -13
@@ -31,38 +31,38 @@ module EventMachine
|
|
31
31
|
# Simple SMTP client
|
32
32
|
#
|
33
33
|
# @example
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
34
|
+
# email = EM::Protocols::SmtpClient.send(
|
35
|
+
# :domain=>"example.com",
|
36
|
+
# :host=>'localhost',
|
37
|
+
# :port=>25, # optional, defaults 25
|
38
|
+
# :starttls=>true, # use ssl
|
39
|
+
# :from=>"sender@example.com",
|
40
|
+
# :to=> ["to_1@example.com", "to_2@example.com"],
|
41
|
+
# :header=> {"Subject" => "This is a subject line"},
|
42
|
+
# :body=> "This is the body of the email"
|
43
|
+
# )
|
44
|
+
# email.callback{
|
45
|
+
# puts 'Email sent!'
|
46
|
+
# }
|
47
|
+
# email.errback{ |e|
|
48
|
+
# puts 'Email failed!'
|
49
|
+
# }
|
50
50
|
#
|
51
51
|
# Sending generated emails (using mailfactory)
|
52
52
|
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
53
|
+
# mail = MailFactory.new
|
54
|
+
# mail.to = 'someone@site.co'
|
55
|
+
# mail.from = 'me@site.com'
|
56
|
+
# mail.subject = 'hi!'
|
57
|
+
# mail.text = 'hello world'
|
58
|
+
# mail.html = '<h1>hello world</h1>'
|
59
59
|
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
60
|
+
# email = EM::P::SmtpClient.send(
|
61
|
+
# :domain=>'site.com',
|
62
|
+
# :from=>mail.from,
|
63
|
+
# :to=>mail.to,
|
64
|
+
# :content=>"#{mail.to_s}\r\n.\r\n"
|
65
|
+
# )
|
66
66
|
#
|
67
67
|
class SmtpClient < Connection
|
68
68
|
include EventMachine::Deferrable
|
data/lib/em/pure_ruby.rb
CHANGED
@@ -177,6 +177,18 @@ module EventMachine
|
|
177
177
|
def set_max_timer_count n
|
178
178
|
end
|
179
179
|
|
180
|
+
# @private
|
181
|
+
def get_sock_opt signature, level, optname
|
182
|
+
selectable = Reactor.instance.get_selectable( signature ) or raise "unknown get_peername target"
|
183
|
+
selectable.getsockopt level, optname
|
184
|
+
end
|
185
|
+
|
186
|
+
# @private
|
187
|
+
def set_sock_opt signature, level, optname, optval
|
188
|
+
selectable = Reactor.instance.get_selectable( signature ) or raise "unknown get_peername target"
|
189
|
+
selectable.setsockopt level, optname, optval
|
190
|
+
end
|
191
|
+
|
180
192
|
# @private
|
181
193
|
def send_file_data sig, filename
|
182
194
|
sz = File.size(filename)
|
data/lib/em/threaded_resource.rb
CHANGED
@@ -29,7 +29,7 @@ module EventMachine
|
|
29
29
|
#
|
30
30
|
# # If we don't care about the result:
|
31
31
|
# pool.perform do |dispatcher|
|
32
|
-
# # The following
|
32
|
+
# # The following block executes inside a dedicated thread, and should not
|
33
33
|
# # access EventMachine things:
|
34
34
|
# dispatcher.dispatch do |cassandra|
|
35
35
|
# cassandra.insert(:Things, '10', 'stuff' => 'things')
|
data/lib/em/version.rb
CHANGED
data/lib/eventmachine.rb
CHANGED
@@ -82,7 +82,8 @@ module EventMachine
|
|
82
82
|
@reactor_running = false
|
83
83
|
@next_tick_queue = []
|
84
84
|
@tails = []
|
85
|
-
@threadpool = nil
|
85
|
+
@threadpool = @threadqueue = @resultqueue = nil
|
86
|
+
@all_threads_spawned = false
|
86
87
|
|
87
88
|
# System errnos
|
88
89
|
# @private
|
@@ -157,7 +158,13 @@ module EventMachine
|
|
157
158
|
# will start without release_machine being called and will immediately throw
|
158
159
|
|
159
160
|
#
|
160
|
-
|
161
|
+
if reactor_running? and @reactor_pid != Process.pid
|
162
|
+
# Reactor was started in a different parent, meaning we have forked.
|
163
|
+
# Clean up reactor state so a new reactor boots up in this child.
|
164
|
+
stop_event_loop
|
165
|
+
release_machine
|
166
|
+
@reactor_running = false
|
167
|
+
end
|
161
168
|
|
162
169
|
tail and @tails.unshift(tail)
|
163
170
|
|
@@ -171,6 +178,7 @@ module EventMachine
|
|
171
178
|
@next_tick_queue ||= []
|
172
179
|
@tails ||= []
|
173
180
|
begin
|
181
|
+
@reactor_pid = Process.pid
|
174
182
|
@reactor_running = true
|
175
183
|
initialize_event_machine
|
176
184
|
(b = blk || block) and add_timer(0, b)
|
@@ -203,6 +211,7 @@ module EventMachine
|
|
203
211
|
@threadqueue = nil
|
204
212
|
@resultqueue = nil
|
205
213
|
@threadpool = nil
|
214
|
+
@all_threads_spawned = false
|
206
215
|
end
|
207
216
|
|
208
217
|
@next_tick_queue = []
|
@@ -254,7 +263,7 @@ module EventMachine
|
|
254
263
|
if self.reactor_running?
|
255
264
|
self.stop_event_loop
|
256
265
|
self.release_machine
|
257
|
-
|
266
|
+
@reactor_running = false
|
258
267
|
end
|
259
268
|
self.run block
|
260
269
|
end
|
@@ -427,7 +436,8 @@ module EventMachine
|
|
427
436
|
# that you must define. When the network server that is started by
|
428
437
|
# start_server accepts a new connection, it instantiates a new
|
429
438
|
# object of an anonymous class that is inherited from {EventMachine::Connection},
|
430
|
-
# *into which your handler module have been included*.
|
439
|
+
# *into which your handler module have been included*. Arguments passed into start_server
|
440
|
+
# after the class name are passed into the constructor during the instantiation.
|
431
441
|
#
|
432
442
|
# Your handler module may override any of the methods in {EventMachine::Connection},
|
433
443
|
# such as {EventMachine::Connection#receive_data}, in order to implement the specific behavior
|
@@ -738,6 +748,7 @@ module EventMachine
|
|
738
748
|
c = klass.new s, *args
|
739
749
|
|
740
750
|
c.instance_variable_set(:@io, io)
|
751
|
+
c.instance_variable_set(:@watch_mode, watch_mode)
|
741
752
|
c.instance_variable_set(:@fd, fd)
|
742
753
|
|
743
754
|
@conns[s] = c
|
@@ -763,7 +774,11 @@ module EventMachine
|
|
763
774
|
#raise "still connected" if @conns.has_key?(handler.signature)
|
764
775
|
return handler if @conns.has_key?(handler.signature)
|
765
776
|
|
766
|
-
s =
|
777
|
+
s = if port
|
778
|
+
connect_server server, port
|
779
|
+
else
|
780
|
+
connect_unix_server server
|
781
|
+
end
|
767
782
|
handler.signature = s
|
768
783
|
@conns[s] = handler
|
769
784
|
block_given? and yield handler
|
@@ -938,10 +953,21 @@ module EventMachine
|
|
938
953
|
cback.call result if cback
|
939
954
|
end
|
940
955
|
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
956
|
+
# Capture the size at the start of this tick...
|
957
|
+
size = @next_tick_mutex.synchronize { @next_tick_queue.size }
|
958
|
+
size.times do |i|
|
959
|
+
callback = @next_tick_mutex.synchronize { @next_tick_queue.shift }
|
960
|
+
begin
|
961
|
+
callback.call
|
962
|
+
ensure
|
963
|
+
# This is a little nasty. The problem is, if an exception occurs during
|
964
|
+
# the callback, then we need to send a signal to the reactor to actually
|
965
|
+
# do some work during the next_tick. The only mechanism we have from the
|
966
|
+
# ruby side is next_tick itself, although ideally, we'd just drop a byte
|
967
|
+
# on the loopback descriptor.
|
968
|
+
EM.next_tick {} if $!
|
969
|
+
end
|
970
|
+
end
|
945
971
|
end
|
946
972
|
|
947
973
|
|
@@ -993,7 +1019,6 @@ module EventMachine
|
|
993
1019
|
# has no constructor.
|
994
1020
|
|
995
1021
|
unless @threadpool
|
996
|
-
require 'thread'
|
997
1022
|
@threadpool = []
|
998
1023
|
@threadqueue = ::Queue.new
|
999
1024
|
@resultqueue = ::Queue.new
|
@@ -1018,6 +1043,19 @@ module EventMachine
|
|
1018
1043
|
end
|
1019
1044
|
@threadpool << thread
|
1020
1045
|
end
|
1046
|
+
@all_threads_spawned = true
|
1047
|
+
end
|
1048
|
+
|
1049
|
+
##
|
1050
|
+
# Returns +true+ if all deferred actions are done executing and their
|
1051
|
+
# callbacks have been fired.
|
1052
|
+
#
|
1053
|
+
def self.defers_finished?
|
1054
|
+
return false if @threadpool and !@all_threads_spawned
|
1055
|
+
return false if @threadqueue and not @threadqueue.empty?
|
1056
|
+
return false if @resultqueue and not @resultqueue.empty?
|
1057
|
+
return false if @threadpool and @threadqueue.num_waiting != @threadpool.size
|
1058
|
+
return true
|
1021
1059
|
end
|
1022
1060
|
|
1023
1061
|
class << self
|
@@ -1393,11 +1431,19 @@ module EventMachine
|
|
1393
1431
|
if opcode == ConnectionUnbound
|
1394
1432
|
if c = @conns.delete( conn_binding )
|
1395
1433
|
begin
|
1396
|
-
if c.original_method(:unbind).arity
|
1434
|
+
if c.original_method(:unbind).arity != 0
|
1397
1435
|
c.unbind(data == 0 ? nil : EventMachine::ERRNOS[data])
|
1398
1436
|
else
|
1399
1437
|
c.unbind
|
1400
1438
|
end
|
1439
|
+
# If this is an attached (but not watched) connection, close the underlying io object.
|
1440
|
+
if c.instance_variable_defined?(:@io) and !c.instance_variable_get(:@watch_mode)
|
1441
|
+
io = c.instance_variable_get(:@io)
|
1442
|
+
begin
|
1443
|
+
io.close
|
1444
|
+
rescue Errno::EBADF, IOError
|
1445
|
+
end
|
1446
|
+
end
|
1401
1447
|
rescue
|
1402
1448
|
@wrapped_exception = $!
|
1403
1449
|
stop
|
data/lib/jeventmachine.rb
CHANGED
@@ -203,6 +203,11 @@ module EventMachine
|
|
203
203
|
Socket.pack_sockaddr_in(*peer)
|
204
204
|
end
|
205
205
|
end
|
206
|
+
def self.get_sockname sig
|
207
|
+
if sockName = @em.getSockName(sig)
|
208
|
+
Socket.pack_sockaddr_in(*sockName)
|
209
|
+
end
|
210
|
+
end
|
206
211
|
# @private
|
207
212
|
def self.attach_fd fileno, watch_mode
|
208
213
|
# 3Aug09: We could pass in the actual SocketChannel, but then it would be modified (set as non-blocking), and
|
File without changes
|
File without changes
|
data/{tasks → rakelib}/test.rake
RENAMED
File without changes
|
data/tests/test_basic.rb
CHANGED
@@ -224,4 +224,71 @@ class TestBasic < Test::Unit::TestCase
|
|
224
224
|
end
|
225
225
|
end
|
226
226
|
end
|
227
|
+
|
228
|
+
def test_schedule_close
|
229
|
+
localhost, port = '127.0.0.1', 9000
|
230
|
+
timer_ran = false
|
231
|
+
num_close_scheduled = nil
|
232
|
+
EM.run do
|
233
|
+
assert_equal 0, EM.num_close_scheduled
|
234
|
+
EM.add_timer(1) { timer_ran = true; EM.stop }
|
235
|
+
EM.start_server localhost, port do |s|
|
236
|
+
s.close_connection
|
237
|
+
num_close_scheduled = EM.num_close_scheduled
|
238
|
+
end
|
239
|
+
EM.connect localhost, port do |c|
|
240
|
+
def c.unbind
|
241
|
+
EM.stop
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
assert !timer_ran
|
246
|
+
assert_equal 1, num_close_scheduled
|
247
|
+
end
|
248
|
+
|
249
|
+
def test_fork_safe
|
250
|
+
return unless cpid = fork { exit! } rescue false
|
251
|
+
|
252
|
+
read, write = IO.pipe
|
253
|
+
EM.run do
|
254
|
+
cpid = fork do
|
255
|
+
write.puts "forked"
|
256
|
+
EM.run do
|
257
|
+
EM.next_tick do
|
258
|
+
write.puts "EM ran"
|
259
|
+
exit!
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
EM.stop
|
264
|
+
end
|
265
|
+
Process.waitall
|
266
|
+
assert_equal "forked\n", read.readline
|
267
|
+
assert_equal "EM ran\n", read.readline
|
268
|
+
ensure
|
269
|
+
read.close rescue nil
|
270
|
+
write.close rescue nil
|
271
|
+
end
|
272
|
+
|
273
|
+
def test_error_handler_idempotent # issue 185
|
274
|
+
errors = []
|
275
|
+
ticks = []
|
276
|
+
EM.error_handler do |e|
|
277
|
+
errors << e
|
278
|
+
end
|
279
|
+
|
280
|
+
EM.run do
|
281
|
+
EM.next_tick do
|
282
|
+
ticks << :first
|
283
|
+
raise
|
284
|
+
end
|
285
|
+
EM.next_tick do
|
286
|
+
ticks << :second
|
287
|
+
end
|
288
|
+
EM.add_timer(0.001) { EM.stop }
|
289
|
+
end
|
290
|
+
|
291
|
+
assert_equal 1, errors.size
|
292
|
+
assert_equal [:first, :second], ticks
|
293
|
+
end
|
227
294
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'em_test_helper'
|
2
|
+
|
3
|
+
class TestIdleConnection < Test::Unit::TestCase
|
4
|
+
if EM.respond_to?(:get_idle_time)
|
5
|
+
def test_idle_time
|
6
|
+
EM.run{
|
7
|
+
conn = EM.connect 'www.google.com', 80
|
8
|
+
EM.add_timer(3){
|
9
|
+
$idle_time = conn.get_idle_time
|
10
|
+
conn.send_data "GET / HTTP/1.0\r\n\r\n"
|
11
|
+
EM.next_tick{
|
12
|
+
$idle_time_after_send = conn.get_idle_time
|
13
|
+
conn.close_connection
|
14
|
+
EM.stop
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
assert_in_delta 3, $idle_time, 0.2
|
20
|
+
assert_equal 0, $idle_time_after_send
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/tests/test_pool.rb
CHANGED
@@ -115,6 +115,41 @@ class TestPool < Test::Unit::TestCase
|
|
115
115
|
assert_equal [:res], pool.contents
|
116
116
|
end
|
117
117
|
|
118
|
+
def test_contents_when_perform_errors_and_on_error_is_not_set
|
119
|
+
pool.add :res
|
120
|
+
assert_equal [:res], pool.contents
|
121
|
+
|
122
|
+
pool.perform do |r|
|
123
|
+
d = EM::DefaultDeferrable.new
|
124
|
+
d.fail
|
125
|
+
d
|
126
|
+
end
|
127
|
+
|
128
|
+
EM.run { EM.next_tick { EM.stop } }
|
129
|
+
|
130
|
+
assert_equal [:res], pool.contents
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_contents_when_perform_errors_and_on_error_is_set
|
134
|
+
pool.add :res
|
135
|
+
res = nil
|
136
|
+
pool.on_error do |r|
|
137
|
+
res = r
|
138
|
+
end
|
139
|
+
assert_equal [:res], pool.contents
|
140
|
+
|
141
|
+
pool.perform do |r|
|
142
|
+
d = EM::DefaultDeferrable.new
|
143
|
+
d.fail 'foo'
|
144
|
+
d
|
145
|
+
end
|
146
|
+
|
147
|
+
EM.run { EM.next_tick { EM.stop } }
|
148
|
+
|
149
|
+
assert_equal :res, res
|
150
|
+
assert_equal [], pool.contents
|
151
|
+
end
|
152
|
+
|
118
153
|
def test_num_waiting
|
119
154
|
pool.add :res
|
120
155
|
assert_equal 0, pool.num_waiting
|
@@ -125,4 +160,35 @@ class TestPool < Test::Unit::TestCase
|
|
125
160
|
assert_equal 10, pool.num_waiting
|
126
161
|
end
|
127
162
|
|
128
|
-
|
163
|
+
def test_exceptions_in_the_work_block_bubble_up_raise_and_fail_the_resource
|
164
|
+
pool.add :res
|
165
|
+
|
166
|
+
res = nil
|
167
|
+
pool.on_error { |r| res = r }
|
168
|
+
pool.perform { raise 'boom' }
|
169
|
+
|
170
|
+
assert_raises(RuntimeError) do
|
171
|
+
EM.run { EM.next_tick { EM.stop } }
|
172
|
+
end
|
173
|
+
|
174
|
+
assert_equal [], pool.contents
|
175
|
+
assert_equal :res, res
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_removed_list_does_not_leak_on_errors
|
179
|
+
pool.add :res
|
180
|
+
|
181
|
+
pool.on_error do |r|
|
182
|
+
# This is actually the wrong thing to do, and not required, but some users
|
183
|
+
# might do it. When they do, they would find that @removed would cause a
|
184
|
+
# slow leak.
|
185
|
+
pool.remove r
|
186
|
+
end
|
187
|
+
|
188
|
+
pool.perform { d = EM::DefaultDeferrable.new; d.fail; d }
|
189
|
+
|
190
|
+
EM.run { EM.next_tick { EM.stop } }
|
191
|
+
assert_equal [], pool.instance_variable_get(:@removed)
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
data/tests/test_processes.rb
CHANGED
@@ -99,6 +99,24 @@ class TestProcesses < Test::Unit::TestCase
|
|
99
99
|
|
100
100
|
assert_equal("hello\n", $out)
|
101
101
|
end
|
102
|
+
|
103
|
+
def test_em_popen_pause_resume
|
104
|
+
c_rx = 0
|
105
|
+
|
106
|
+
test_client = Module.new do
|
107
|
+
define_method :receive_data do |data|
|
108
|
+
c_rx += 1
|
109
|
+
pause
|
110
|
+
EM.add_timer(0.5) { EM.stop }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
EM.run{
|
115
|
+
EM.popen('cat /dev/random', test_client)
|
116
|
+
}
|
117
|
+
|
118
|
+
assert_equal 1, c_rx
|
119
|
+
end
|
102
120
|
else
|
103
121
|
warn "EM.popen not implemented, skipping tests in #{__FILE__}"
|
104
122
|
|
@@ -24,6 +24,7 @@ class TestProxyConnection < Test::Unit::TestCase
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def unbind
|
27
|
+
$proxied_bytes = self.get_proxied_bytes
|
27
28
|
@client.close_connection_after_writing
|
28
29
|
end
|
29
30
|
end
|
@@ -94,7 +95,7 @@ class TestProxyConnection < Test::Unit::TestCase
|
|
94
95
|
end
|
95
96
|
|
96
97
|
def receive_data(data)
|
97
|
-
EM.connect("127.0.0.1", @port, ProxyConnection, self, data)
|
98
|
+
@proxy = EM.connect("127.0.0.1", @port, ProxyConnection, self, data)
|
98
99
|
end
|
99
100
|
end
|
100
101
|
|
@@ -134,6 +135,17 @@ class TestProxyConnection < Test::Unit::TestCase
|
|
134
135
|
assert_equal("I know!", $client_data)
|
135
136
|
end
|
136
137
|
|
138
|
+
def test_proxied_bytes
|
139
|
+
EM.run {
|
140
|
+
EM.start_server("127.0.0.1", @port, Server)
|
141
|
+
EM.start_server("127.0.0.1", @proxy_port, ProxyServer, @port)
|
142
|
+
EM.connect("127.0.0.1", @proxy_port, Client)
|
143
|
+
}
|
144
|
+
|
145
|
+
assert_equal("I know!", $client_data)
|
146
|
+
assert_equal("I know!".bytesize, $proxied_bytes)
|
147
|
+
end
|
148
|
+
|
137
149
|
def test_partial_proxy_connection
|
138
150
|
EM.run {
|
139
151
|
EM.start_server("127.0.0.1", @port, Server)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'em_test_helper'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
class TestSetSockOpt < Test::Unit::TestCase
|
5
|
+
|
6
|
+
if EM.respond_to? :set_sock_opt
|
7
|
+
def setup
|
8
|
+
assert(!EM.reactor_running?)
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
assert(!EM.reactor_running?)
|
13
|
+
end
|
14
|
+
|
15
|
+
#-------------------------------------
|
16
|
+
|
17
|
+
def test_set_sock_opt
|
18
|
+
test = self
|
19
|
+
EM.run do
|
20
|
+
EM.connect 'google.com', 80, Module.new {
|
21
|
+
define_method :post_init do
|
22
|
+
val = set_sock_opt Socket::SOL_SOCKET, Socket::SO_DEBUG, true
|
23
|
+
test.assert_equal 0, val
|
24
|
+
EM.stop
|
25
|
+
end
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
else
|
30
|
+
warn "EM.set_sock_opt not implemented, skipping tests in #{__FILE__}"
|
31
|
+
|
32
|
+
# Because some rubies will complain if a TestCase class has no tests
|
33
|
+
def test_em_set_sock_opt_unsupported
|
34
|
+
assert true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/tests/test_unbind_reason.rb
CHANGED
@@ -2,6 +2,15 @@ require 'em_test_helper'
|
|
2
2
|
require 'socket'
|
3
3
|
|
4
4
|
class TestUnbindReason < Test::Unit::TestCase
|
5
|
+
|
6
|
+
class StubConnection < EM::Connection
|
7
|
+
attr_reader :error
|
8
|
+
def unbind(reason = nil)
|
9
|
+
@error = reason
|
10
|
+
EM.stop
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
5
14
|
def test_connect_timeout
|
6
15
|
error = nil
|
7
16
|
EM.run {
|
@@ -13,7 +22,7 @@ class TestUnbindReason < Test::Unit::TestCase
|
|
13
22
|
}
|
14
23
|
conn.pending_connect_timeout = 0.1
|
15
24
|
}
|
16
|
-
assert_equal
|
25
|
+
assert_equal Errno::ETIMEDOUT, error
|
17
26
|
end
|
18
27
|
|
19
28
|
def test_connect_refused
|
@@ -26,6 +35,14 @@ class TestUnbindReason < Test::Unit::TestCase
|
|
26
35
|
end
|
27
36
|
}
|
28
37
|
}
|
29
|
-
assert_equal
|
38
|
+
assert_equal Errno::ECONNREFUSED, error
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_optional_argument
|
42
|
+
conn = nil
|
43
|
+
EM.run {
|
44
|
+
conn = EM.connect '127.0.0.1', 12388, StubConnection
|
45
|
+
}
|
46
|
+
assert_equal Errno::ECONNREFUSED, conn.error
|
30
47
|
end
|
31
48
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eventmachine-maglev-
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.rc.4
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,22 +10,22 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-08-17 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake-compiler
|
17
|
-
requirement: &
|
17
|
+
requirement: &70169512878700 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
|
-
- -
|
20
|
+
- - ~>
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: 0.8.1
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *70169512878700
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: yard
|
28
|
-
requirement: &
|
28
|
+
requirement: &70169512877400 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 0.7.2
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *70169512877400
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: bluecloth
|
39
|
-
requirement: &
|
39
|
+
requirement: &70169512876360 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
version: '0'
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *70169512876360
|
48
48
|
description: ! 'EventMachine implements a fast, single-threaded engine for arbitrary
|
49
49
|
network
|
50
50
|
|
@@ -193,9 +193,9 @@ files:
|
|
193
193
|
- lib/em/version.rb
|
194
194
|
- lib/eventmachine.rb
|
195
195
|
- lib/jeventmachine.rb
|
196
|
-
-
|
197
|
-
-
|
198
|
-
-
|
196
|
+
- rakelib/cpp.rake_example
|
197
|
+
- rakelib/package.rake
|
198
|
+
- rakelib/test.rake
|
199
199
|
- tests/client.crt
|
200
200
|
- tests/client.key
|
201
201
|
- tests/em_test_helper.rb
|
@@ -216,6 +216,7 @@ files:
|
|
216
216
|
- tests/test_hc.rb
|
217
217
|
- tests/test_httpclient.rb
|
218
218
|
- tests/test_httpclient2.rb
|
219
|
+
- tests/test_idle_connection.rb
|
219
220
|
- tests/test_inactivity_timeout.rb
|
220
221
|
- tests/test_kb.rb
|
221
222
|
- tests/test_ltp.rb
|
@@ -235,6 +236,7 @@ files:
|
|
235
236
|
- tests/test_sasl.rb
|
236
237
|
- tests/test_send_file.rb
|
237
238
|
- tests/test_servers.rb
|
239
|
+
- tests/test_set_sock_opt.rb
|
238
240
|
- tests/test_shutdown_hooks.rb
|
239
241
|
- tests/test_smtpclient.rb
|
240
242
|
- tests/test_smtpserver.rb
|