eventmachine 0.12.8-java → 0.12.10-java
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/.gitignore +2 -1
- data/Rakefile +155 -45
- data/eventmachine.gemspec +4 -5
- data/ext/binder.cpp +13 -14
- data/ext/binder.h +5 -7
- data/ext/cmain.cpp +184 -42
- data/ext/cplusplus.cpp +20 -20
- data/ext/ed.cpp +242 -81
- data/ext/ed.h +39 -22
- data/ext/em.cpp +127 -108
- data/ext/em.h +27 -18
- data/ext/emwin.cpp +3 -3
- data/ext/eventmachine.h +49 -38
- data/ext/eventmachine_cpp.h +4 -4
- data/ext/extconf.rb +28 -13
- data/ext/fastfilereader/extconf.rb +11 -5
- data/ext/project.h +12 -1
- data/ext/rubymain.cpp +222 -103
- data/ext/ssl.cpp +3 -3
- data/ext/ssl.h +2 -2
- data/java/src/com/rubyeventmachine/EmReactor.java +396 -249
- data/java/src/com/rubyeventmachine/EventableChannel.java +16 -4
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +23 -5
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +181 -61
- data/java/src/com/rubyeventmachine/{Application.java → application/Application.java} +25 -31
- data/java/src/com/rubyeventmachine/{Connection.java → application/Connection.java} +2 -2
- data/java/src/com/rubyeventmachine/{ConnectionFactory.java → application/ConnectionFactory.java} +1 -1
- data/java/src/com/rubyeventmachine/{DefaultConnectionFactory.java → application/DefaultConnectionFactory.java} +2 -2
- data/java/src/com/rubyeventmachine/{PeriodicTimer.java → application/PeriodicTimer.java} +1 -1
- data/java/src/com/rubyeventmachine/{Timer.java → application/Timer.java} +1 -1
- data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +1 -0
- data/java/src/com/rubyeventmachine/tests/ConnectTest.java +4 -2
- data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +1 -1
- data/java/src/com/rubyeventmachine/tests/TestServers.java +1 -0
- data/java/src/com/rubyeventmachine/tests/TestTimers.java +1 -0
- data/lib/em/connection.rb +71 -12
- data/lib/em/deferrable.rb +5 -0
- data/lib/em/protocols.rb +1 -0
- data/lib/em/protocols/httpclient2.rb +8 -0
- data/lib/em/protocols/line_and_text.rb +0 -1
- data/lib/em/protocols/linetext2.rb +1 -0
- data/lib/em/protocols/object_protocol.rb +8 -2
- data/lib/em/protocols/smtpclient.rb +42 -16
- data/lib/em/protocols/socks4.rb +66 -0
- data/lib/em/queue.rb +1 -1
- data/lib/em/timers.rb +2 -1
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +125 -169
- data/lib/jeventmachine.rb +124 -9
- data/tasks/{cpp.rake → cpp.rake_example} +0 -0
- data/tests/test_attach.rb +29 -4
- data/tests/test_basic.rb +1 -2
- data/tests/test_connection_count.rb +10 -20
- data/tests/test_epoll.rb +0 -2
- data/tests/test_get_sock_opt.rb +30 -0
- data/tests/test_httpclient2.rb +3 -3
- data/tests/test_inactivity_timeout.rb +21 -1
- data/tests/test_ltp.rb +0 -6
- data/tests/test_next_tick.rb +0 -2
- data/tests/test_pause.rb +70 -0
- data/tests/test_pending_connect_timeout.rb +48 -0
- data/tests/test_ssl_args.rb +16 -5
- data/tests/test_timers.rb +22 -1
- metadata +59 -52
- data/tasks/project.rake +0 -79
- data/tasks/tests.rake +0 -193
data/lib/jeventmachine.rb
CHANGED
@@ -29,6 +29,32 @@
|
|
29
29
|
|
30
30
|
require 'java'
|
31
31
|
require 'em_reactor'
|
32
|
+
require 'socket'
|
33
|
+
|
34
|
+
java_import java.io.FileDescriptor
|
35
|
+
java_import java.nio.channels.SocketChannel
|
36
|
+
java_import java.lang.reflect.Field
|
37
|
+
|
38
|
+
module JavaFields
|
39
|
+
def set_field(key, value)
|
40
|
+
field = getClass.getDeclaredField(key)
|
41
|
+
field.setAccessible(true)
|
42
|
+
if field.getType.toString == 'int'
|
43
|
+
field.setInt(self, value)
|
44
|
+
else
|
45
|
+
field.set(self, value)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_field(key)
|
50
|
+
field = getClass.getDeclaredField(key)
|
51
|
+
field.setAccessible(true)
|
52
|
+
field.get(self)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
FileDescriptor.send :include, JavaFields
|
57
|
+
SocketChannel.send :include, JavaFields
|
32
58
|
|
33
59
|
module EventMachine
|
34
60
|
# TODO: These event numbers are defined in way too many places.
|
@@ -39,20 +65,29 @@ module EventMachine
|
|
39
65
|
ConnectionAccepted = 103
|
40
66
|
ConnectionCompleted = 104
|
41
67
|
LoopbreakSignalled = 105
|
68
|
+
ConnectionNotifyReadable = 106
|
69
|
+
ConnectionNotifyWritable = 107
|
70
|
+
SslHandshakeCompleted = 108
|
71
|
+
|
72
|
+
# Exceptions that are defined in rubymain.cpp
|
73
|
+
class ConnectionNotBound < RuntimeError; end
|
74
|
+
class UnknownTimerFired < RuntimeError; end
|
75
|
+
class Unsupported < RuntimeError; end
|
42
76
|
|
43
77
|
# This thunk class used to be called EM, but that caused conflicts with
|
44
78
|
# the alias "EM" for module EventMachine. (FC, 20Jun08)
|
45
79
|
class JEM < com.rubyeventmachine.EmReactor
|
46
|
-
def eventCallback a1, a2, a3
|
47
|
-
s = String.from_java_bytes(a3.array[a3.position...a3.limit])
|
48
|
-
EventMachine::event_callback a1, a2, s
|
49
|
-
|
50
|
-
end
|
51
|
-
class Connection < com.rubyeventmachine.Connection
|
52
|
-
def associate_callback_target sig
|
53
|
-
# No-op for the time being.
|
80
|
+
def eventCallback a1, a2, a3, a4
|
81
|
+
s = String.from_java_bytes(a3.array[a3.position...a3.limit]) if a3
|
82
|
+
EventMachine::event_callback a1, a2, s || a4
|
83
|
+
nil
|
54
84
|
end
|
55
85
|
end
|
86
|
+
# class Connection < com.rubyeventmachine.Connection
|
87
|
+
# def associate_callback_target sig
|
88
|
+
# # No-op for the time being.
|
89
|
+
# end
|
90
|
+
# end
|
56
91
|
def self.initialize_event_machine
|
57
92
|
@em = JEM.new
|
58
93
|
end
|
@@ -88,7 +123,7 @@ module EventMachine
|
|
88
123
|
bind_connect_server nil, nil, server, port
|
89
124
|
end
|
90
125
|
def self.bind_connect_server bind_addr, bind_port, server, port
|
91
|
-
@em.connectTcpServer bind_addr, bind_port, server, port
|
126
|
+
@em.connectTcpServer bind_addr, bind_port.to_i, server, port
|
92
127
|
end
|
93
128
|
def self.close_connection sig, after_writing
|
94
129
|
@em.closeConnection sig, after_writing
|
@@ -112,6 +147,18 @@ module EventMachine
|
|
112
147
|
# Epoll is a no-op for Java.
|
113
148
|
# The latest Java versions run epoll when possible in NIO.
|
114
149
|
end
|
150
|
+
def self.epoll= val
|
151
|
+
end
|
152
|
+
def self.kqueue
|
153
|
+
end
|
154
|
+
def self.kqueue= val
|
155
|
+
end
|
156
|
+
def self.epoll?
|
157
|
+
false
|
158
|
+
end
|
159
|
+
def self.kqueue?
|
160
|
+
false
|
161
|
+
end
|
115
162
|
def self.set_rlimit_nofile n_descriptors
|
116
163
|
# Currently a no-op for Java.
|
117
164
|
end
|
@@ -128,10 +175,78 @@ module EventMachine
|
|
128
175
|
end
|
129
176
|
def self.set_max_timer_count num
|
130
177
|
# harmless no-op in Java. There's no built-in timer limit.
|
178
|
+
@max_timer_count = num
|
179
|
+
end
|
180
|
+
def self.get_max_timer_count
|
181
|
+
# harmless no-op in Java. There's no built-in timer limit.
|
182
|
+
@max_timer_count || 100_000
|
131
183
|
end
|
132
184
|
def self.library_type
|
133
185
|
:java
|
134
186
|
end
|
187
|
+
def self.get_peername sig
|
188
|
+
if peer = @em.getPeerName(sig)
|
189
|
+
Socket.pack_sockaddr_in *peer
|
190
|
+
end
|
191
|
+
end
|
192
|
+
def self.attach_fd fileno, watch_mode
|
193
|
+
# 3Aug09: We could pass in the actual SocketChannel, but then it would be modified (set as non-blocking), and
|
194
|
+
# we would need some logic to make sure detach_fd below didn't clobber it. For now, we just always make a new
|
195
|
+
# SocketChannel for the underlying file descriptor
|
196
|
+
# if fileno.java_kind_of? SocketChannel
|
197
|
+
# ch = fileno
|
198
|
+
# ch.configureBlocking(false)
|
199
|
+
# fileno = nil
|
200
|
+
# elsif fileno.java_kind_of? java.nio.channels.Channel
|
201
|
+
|
202
|
+
if fileno.java_kind_of? java.nio.channels.Channel
|
203
|
+
field = fileno.getClass.getDeclaredField('fdVal')
|
204
|
+
field.setAccessible(true)
|
205
|
+
fileno = field.get(fileno)
|
206
|
+
else
|
207
|
+
raise ArgumentError, 'attach_fd requires Java Channel or POSIX fileno' unless fileno.is_a? Fixnum
|
208
|
+
end
|
209
|
+
|
210
|
+
if fileno == 0
|
211
|
+
raise "can't open STDIN as selectable in Java =("
|
212
|
+
elsif fileno.is_a? Fixnum
|
213
|
+
# 8Aug09: The following code is specific to the sun jvm's SocketChannelImpl. Is there a cross-platform
|
214
|
+
# way of implementing this? If so, also remember to update EventableSocketChannel#close and #cleanup
|
215
|
+
fd = FileDescriptor.new
|
216
|
+
fd.set_field 'fd', fileno
|
217
|
+
|
218
|
+
ch = SocketChannel.open
|
219
|
+
ch.configureBlocking(false)
|
220
|
+
ch.kill
|
221
|
+
ch.set_field 'fd', fd
|
222
|
+
ch.set_field 'fdVal', fileno
|
223
|
+
ch.set_field 'state', ch.get_field('ST_CONNECTED')
|
224
|
+
end
|
225
|
+
|
226
|
+
@em.attachChannel(ch,watch_mode)
|
227
|
+
end
|
228
|
+
def self.detach_fd sig
|
229
|
+
if ch = @em.detachChannel(sig)
|
230
|
+
ch.get_field 'fdVal'
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def self.set_notify_readable sig, mode
|
235
|
+
@em.setNotifyReadable(sig, mode)
|
236
|
+
end
|
237
|
+
def self.set_notify_writable sig, mode
|
238
|
+
@em.setNotifyWritable(sig, mode)
|
239
|
+
end
|
240
|
+
|
241
|
+
def self.is_notify_readable sig
|
242
|
+
@em.isNotifyReadable(sig)
|
243
|
+
end
|
244
|
+
def self.is_notify_writable sig
|
245
|
+
@em.isNotifyWritable(sig)
|
246
|
+
end
|
247
|
+
def self.get_connection_count
|
248
|
+
@em.getConnectionCount
|
249
|
+
end
|
135
250
|
|
136
251
|
class Connection
|
137
252
|
def associate_callback_target sig
|
File without changes
|
data/tests/test_attach.rb
CHANGED
@@ -34,6 +34,7 @@ class TestAttach < Test::Unit::TestCase
|
|
34
34
|
|
35
35
|
class EchoClient < EM::Connection
|
36
36
|
def initialize
|
37
|
+
self.notify_readable = true
|
37
38
|
$sock.write("abc\n")
|
38
39
|
end
|
39
40
|
|
@@ -54,16 +55,17 @@ class TestAttach < Test::Unit::TestCase
|
|
54
55
|
EM.run{
|
55
56
|
EM.start_server Host, Port, EchoServer
|
56
57
|
$sock = TCPSocket.new Host, Port
|
57
|
-
EM.
|
58
|
+
EM.watch $sock, EchoClient
|
58
59
|
}
|
59
60
|
|
60
61
|
assert_equal $read, "abc\n"
|
61
|
-
|
62
|
+
unless defined? JRuby # jruby filenos are not real
|
63
|
+
assert_equal $fd, $sock.fileno
|
64
|
+
end
|
62
65
|
assert_equal false, $sock.closed?
|
63
66
|
assert_equal $sock.readline, "def\n"
|
64
67
|
end
|
65
68
|
|
66
|
-
|
67
69
|
module PipeWatch
|
68
70
|
def notify_readable
|
69
71
|
$read = $r.readline
|
@@ -74,13 +76,36 @@ class TestAttach < Test::Unit::TestCase
|
|
74
76
|
def test_attach_pipe
|
75
77
|
EM.run{
|
76
78
|
$r, $w = IO.pipe
|
77
|
-
EM.
|
79
|
+
EM.watch $r, PipeWatch do |c|
|
80
|
+
c.notify_readable = true
|
81
|
+
end
|
78
82
|
$w.write("ghi\n")
|
79
83
|
}
|
80
84
|
|
81
85
|
assert_equal $read, "ghi\n"
|
82
86
|
end
|
83
87
|
|
88
|
+
def test_set_readable
|
89
|
+
EM.run{
|
90
|
+
$r, $w = IO.pipe
|
91
|
+
c = EM.watch $r, PipeWatch do |c|
|
92
|
+
c.notify_readable = false
|
93
|
+
end
|
94
|
+
|
95
|
+
EM.next_tick{
|
96
|
+
$before = c.notify_readable?
|
97
|
+
c.notify_readable = true
|
98
|
+
$after = c.notify_readable?
|
99
|
+
}
|
100
|
+
|
101
|
+
$w.write("jkl\n")
|
102
|
+
}
|
103
|
+
|
104
|
+
assert !$before
|
105
|
+
assert $after
|
106
|
+
assert_equal $read, "jkl\n"
|
107
|
+
end
|
108
|
+
|
84
109
|
module PipeReader
|
85
110
|
def receive_data data
|
86
111
|
$read = data
|
data/tests/test_basic.rb
CHANGED
@@ -14,32 +14,22 @@ class TestConnectionCount < Test::Unit::TestCase
|
|
14
14
|
|
15
15
|
module Client
|
16
16
|
def connection_completed
|
17
|
-
|
18
|
-
|
19
|
-
EM.stop
|
20
|
-
}
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
module Server
|
25
|
-
def post_init
|
26
|
-
$server_connected = EM.connection_count
|
17
|
+
$client_conns += 1
|
18
|
+
EM.stop if $client_conns == 3
|
27
19
|
end
|
28
20
|
end
|
29
21
|
|
30
22
|
def test_with_some_connections
|
31
23
|
EM.run {
|
32
|
-
$
|
33
|
-
EM.
|
34
|
-
|
35
|
-
EM.
|
36
|
-
|
37
|
-
}
|
24
|
+
$client_conns = 0
|
25
|
+
$initial_conns = EM.connection_count
|
26
|
+
EM.start_server("127.0.0.1", 9999)
|
27
|
+
$server_conns = EM.connection_count
|
28
|
+
3.times { EM.connect("127.0.0.1", 9999, Client) }
|
38
29
|
}
|
39
30
|
|
40
|
-
assert_equal(0, $
|
41
|
-
assert_equal(1, $
|
42
|
-
assert_equal(
|
43
|
-
assert_equal(3, $client_connected)
|
31
|
+
assert_equal(0, $initial_conns)
|
32
|
+
assert_equal(1, $server_conns)
|
33
|
+
assert_equal(4, $client_conns + $server_conns)
|
44
34
|
end
|
45
35
|
end
|
data/tests/test_epoll.rb
CHANGED
@@ -94,7 +94,6 @@ class TestEpoll < Test::Unit::TestCase
|
|
94
94
|
n = 0
|
95
95
|
work_proc = proc {n += 1}
|
96
96
|
callback_proc = proc {EM.stop}
|
97
|
-
EM.epoll
|
98
97
|
EM.run {
|
99
98
|
EM.defer work_proc, callback_proc
|
100
99
|
}
|
@@ -120,7 +119,6 @@ class TestEpoll < Test::Unit::TestCase
|
|
120
119
|
|
121
120
|
def test_datagrams
|
122
121
|
$in = $out = ""
|
123
|
-
EM.epoll
|
124
122
|
EM.run {
|
125
123
|
EM.open_datagram_socket "127.0.0.1", 9500, TestDatagramServer
|
126
124
|
EM.open_datagram_socket "127.0.0.1", 0, TestDatagramClient
|
@@ -0,0 +1,30 @@
|
|
1
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'socket'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class TestGetSockOpt < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
assert(!EM.reactor_running?)
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
assert(!EM.reactor_running?)
|
14
|
+
end
|
15
|
+
|
16
|
+
#-------------------------------------
|
17
|
+
|
18
|
+
def test_get_sock_opt
|
19
|
+
test = self
|
20
|
+
EM.run do
|
21
|
+
EM.connect 'google.com', 80, Module.new {
|
22
|
+
define_method :connection_completed do
|
23
|
+
val = get_sock_opt Socket::SOL_SOCKET, Socket::SO_ERROR
|
24
|
+
test.assert_equal "\0\0\0\0", val
|
25
|
+
EM.stop
|
26
|
+
end
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/tests/test_httpclient2.rb
CHANGED
@@ -80,7 +80,7 @@ class TestHttpClient2 < Test::Unit::TestCase
|
|
80
80
|
def test_get
|
81
81
|
content = nil
|
82
82
|
EM.run {
|
83
|
-
http = EM::P::HttpClient2.connect "
|
83
|
+
http = EM::P::HttpClient2.connect "google.com", 80
|
84
84
|
d = http.get "/"
|
85
85
|
d.callback {
|
86
86
|
content = d.content
|
@@ -96,7 +96,7 @@ class TestHttpClient2 < Test::Unit::TestCase
|
|
96
96
|
def _test_get_multiple
|
97
97
|
content = nil
|
98
98
|
EM.run {
|
99
|
-
http = EM::P::HttpClient2.connect "
|
99
|
+
http = EM::P::HttpClient2.connect "google.com", 80
|
100
100
|
d = http.get "/"
|
101
101
|
d.callback {
|
102
102
|
e = http.get "/"
|
@@ -112,7 +112,7 @@ class TestHttpClient2 < Test::Unit::TestCase
|
|
112
112
|
def test_get_pipeline
|
113
113
|
headers, headers2 = nil, nil
|
114
114
|
EM.run {
|
115
|
-
http = EM::P::HttpClient2.connect "
|
115
|
+
http = EM::P::HttpClient2.connect "google.com", 80
|
116
116
|
d = http.get("/")
|
117
117
|
d.callback {
|
118
118
|
headers = d.headers
|
@@ -15,7 +15,7 @@ class TestInactivityTimeout < Test::Unit::TestCase
|
|
15
15
|
assert_equal(0.0, $timeout)
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
18
|
+
def test_set_and_get
|
19
19
|
$timeout = nil
|
20
20
|
EM.run {
|
21
21
|
c = EM.connect("127.0.0.1", 54321)
|
@@ -27,4 +27,24 @@ class TestInactivityTimeout < Test::Unit::TestCase
|
|
27
27
|
assert_equal(2.5, $timeout)
|
28
28
|
end
|
29
29
|
|
30
|
+
module TimeoutHandler
|
31
|
+
def unbind
|
32
|
+
EM.stop
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_for_real
|
37
|
+
EM.run {
|
38
|
+
EM.heartbeat_interval = 0.1
|
39
|
+
EM.start_server("127.0.0.1", 12345)
|
40
|
+
EM.add_timer(0.2) {
|
41
|
+
$start = Time.now
|
42
|
+
c = EM.connect("127.0.0.1", 12345, TimeoutHandler)
|
43
|
+
c.comm_inactivity_timeout = 2.5
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
assert_in_delta(2.5, (Time.now - $start), 0.3)
|
48
|
+
end
|
49
|
+
|
30
50
|
end
|
data/tests/test_ltp.rb
CHANGED
@@ -58,9 +58,6 @@ class TestLineAndTextProtocol < Test::Unit::TestCase
|
|
58
58
|
|
59
59
|
|
60
60
|
def test_simple_lines
|
61
|
-
# THIS TEST CURRENTLY FAILS IN JRUBY.
|
62
|
-
assert( RUBY_PLATFORM !~ /java/ )
|
63
|
-
|
64
61
|
lines_received = []
|
65
62
|
EventMachine.run {
|
66
63
|
EventMachine.start_server( TestHost, TestPort, SimpleLineTest ) do |conn|
|
@@ -85,9 +82,6 @@ class TestLineAndTextProtocol < Test::Unit::TestCase
|
|
85
82
|
end
|
86
83
|
|
87
84
|
def test_overlength_lines
|
88
|
-
# THIS TEST CURRENTLY FAILS IN JRUBY.
|
89
|
-
assert( RUBY_PLATFORM !~ /java/ )
|
90
|
-
|
91
85
|
lines_received = []
|
92
86
|
EventMachine.run {
|
93
87
|
EventMachine.start_server( TestHost, TestPort, SimpleLineTest ) do |conn|
|
data/tests/test_next_tick.rb
CHANGED
@@ -33,7 +33,6 @@ class TestNextTick < Test::Unit::TestCase
|
|
33
33
|
|
34
34
|
def test_tick_arg
|
35
35
|
pr = proc {EM.stop}
|
36
|
-
EM.epoll
|
37
36
|
EM.run {
|
38
37
|
EM.next_tick pr
|
39
38
|
}
|
@@ -41,7 +40,6 @@ class TestNextTick < Test::Unit::TestCase
|
|
41
40
|
end
|
42
41
|
|
43
42
|
def test_tick_block
|
44
|
-
EM.epoll
|
45
43
|
EM.run {
|
46
44
|
EM.next_tick {EM.stop}
|
47
45
|
}
|
data/tests/test_pause.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'socket'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class TestPause < Test::Unit::TestCase
|
7
|
+
TestHost = "127.0.0.1"
|
8
|
+
TestPort = 9070
|
9
|
+
|
10
|
+
def setup
|
11
|
+
assert(!EM.reactor_running?)
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
assert(!EM.reactor_running?)
|
16
|
+
end
|
17
|
+
|
18
|
+
#-------------------------------------
|
19
|
+
|
20
|
+
def test_pause_resume
|
21
|
+
test = self
|
22
|
+
server = nil
|
23
|
+
|
24
|
+
s_rx = c_rx = 0
|
25
|
+
|
26
|
+
EM.run do
|
27
|
+
EM.start_server TestHost, TestPort, Module.new {
|
28
|
+
define_method :post_init do
|
29
|
+
server = self
|
30
|
+
end
|
31
|
+
|
32
|
+
define_method :receive_data do |data|
|
33
|
+
s_rx += 1
|
34
|
+
|
35
|
+
EM.add_periodic_timer(0.01) { send_data 'hi' }
|
36
|
+
send_data 'hi'
|
37
|
+
|
38
|
+
# pause server, now no outgoing data will actually
|
39
|
+
# be sent and no more incoming data will be received
|
40
|
+
pause
|
41
|
+
end
|
42
|
+
}
|
43
|
+
|
44
|
+
c = EM.connect TestHost, TestPort, Module.new {
|
45
|
+
define_method :receive_data do |data|
|
46
|
+
c_rx += 1
|
47
|
+
end
|
48
|
+
}
|
49
|
+
EM.add_periodic_timer(0.01) { c.send_data 'hi' }
|
50
|
+
|
51
|
+
EM.add_timer(1) do
|
52
|
+
test.assert_equal 1, s_rx
|
53
|
+
test.assert_equal 0, c_rx
|
54
|
+
test.assert server.paused?
|
55
|
+
|
56
|
+
# resume server, queued outgoing and incoming data will be flushed
|
57
|
+
server.resume
|
58
|
+
|
59
|
+
test.assert ! server.paused?
|
60
|
+
|
61
|
+
EM.add_timer(1) do
|
62
|
+
test.assert server.paused?
|
63
|
+
test.assert s_rx >= 2
|
64
|
+
test.assert c_rx >= 1
|
65
|
+
EM.stop_event_loop
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|