eventmachine 0.12.6-java → 0.12.8-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/{docs/README → README} +21 -13
- data/Rakefile +5 -3
- data/docs/DEFERRABLES +0 -5
- data/docs/INSTALL +2 -4
- data/docs/LEGAL +1 -1
- data/docs/LIGHTWEIGHT_CONCURRENCY +0 -2
- data/docs/PURE_RUBY +0 -2
- data/docs/RELEASE_NOTES +0 -2
- data/docs/SMTP +0 -7
- data/docs/SPAWNED_PROCESSES +0 -4
- data/docs/TODO +0 -2
- data/eventmachine.gemspec +17 -8
- data/examples/ex_channel.rb +43 -0
- data/examples/ex_queue.rb +2 -0
- data/examples/helper.rb +2 -0
- data/ext/cmain.cpp +119 -20
- data/ext/cplusplus.cpp +15 -6
- data/ext/ed.cpp +303 -93
- data/ext/ed.h +49 -22
- data/ext/em.cpp +368 -42
- data/ext/em.h +43 -6
- data/ext/eventmachine.h +21 -8
- data/ext/eventmachine_cpp.h +1 -0
- data/ext/extconf.rb +4 -0
- data/ext/kb.cpp +1 -2
- data/ext/pipe.cpp +1 -3
- data/ext/project.h +21 -0
- data/ext/rubymain.cpp +232 -32
- data/ext/ssl.cpp +38 -1
- data/ext/ssl.h +5 -1
- data/java/src/com/rubyeventmachine/Application.java +7 -3
- data/java/src/com/rubyeventmachine/EmReactor.java +16 -1
- data/java/src/com/rubyeventmachine/tests/ConnectTest.java +25 -3
- data/lib/{protocols → em}/buftok.rb +16 -5
- data/lib/em/callback.rb +26 -0
- data/lib/em/channel.rb +57 -0
- data/lib/em/connection.rb +505 -0
- data/lib/em/deferrable.rb +144 -165
- data/lib/em/file_watch.rb +54 -0
- data/lib/em/future.rb +24 -25
- data/lib/em/messages.rb +1 -1
- data/lib/em/process_watch.rb +44 -0
- data/lib/em/processes.rb +58 -52
- data/lib/em/protocols.rb +35 -0
- data/lib/em/protocols/header_and_content.rb +138 -0
- data/lib/em/protocols/httpclient.rb +263 -0
- data/lib/em/protocols/httpclient2.rb +582 -0
- data/lib/{protocols → em/protocols}/line_and_text.rb +2 -2
- data/lib/em/protocols/linetext2.rb +160 -0
- data/lib/{protocols → em/protocols}/memcache.rb +37 -7
- data/lib/em/protocols/object_protocol.rb +39 -0
- data/lib/em/protocols/postgres3.rb +247 -0
- data/lib/em/protocols/saslauth.rb +175 -0
- data/lib/em/protocols/smtpclient.rb +331 -0
- data/lib/em/protocols/smtpserver.rb +547 -0
- data/lib/em/protocols/stomp.rb +200 -0
- data/lib/{protocols → em/protocols}/tcptest.rb +21 -25
- data/lib/em/queue.rb +61 -0
- data/lib/em/spawnable.rb +53 -56
- data/lib/em/streamer.rb +92 -74
- data/lib/em/timers.rb +55 -0
- data/lib/em/version.rb +3 -0
- data/lib/eventmachine.rb +1008 -1298
- data/lib/evma.rb +1 -1
- data/lib/jeventmachine.rb +106 -101
- data/lib/pr_eventmachine.rb +47 -36
- data/tasks/project.rake +2 -1
- data/tests/client.crt +31 -0
- data/tests/client.key +51 -0
- data/tests/test_attach.rb +18 -0
- data/tests/test_basic.rb +108 -54
- data/tests/test_channel.rb +63 -0
- data/tests/test_connection_count.rb +2 -2
- data/tests/test_epoll.rb +109 -110
- data/tests/test_errors.rb +36 -36
- data/tests/test_exc.rb +22 -25
- data/tests/test_file_watch.rb +49 -0
- data/tests/test_futures.rb +77 -93
- data/tests/test_hc.rb +2 -2
- data/tests/test_httpclient.rb +55 -52
- data/tests/test_httpclient2.rb +110 -112
- data/tests/test_inactivity_timeout.rb +30 -0
- data/tests/test_kb.rb +8 -9
- data/tests/test_ltp2.rb +274 -277
- data/tests/test_next_tick.rb +91 -65
- data/tests/test_object_protocol.rb +37 -0
- data/tests/test_process_watch.rb +48 -0
- data/tests/test_processes.rb +56 -23
- data/tests/test_proxy_connection.rb +92 -0
- data/tests/test_pure.rb +1 -5
- data/tests/test_queue.rb +44 -0
- data/tests/test_running.rb +9 -14
- data/tests/test_sasl.rb +32 -34
- data/tests/test_send_file.rb +175 -176
- data/tests/test_servers.rb +37 -41
- data/tests/test_smtpserver.rb +47 -55
- data/tests/test_spawn.rb +284 -291
- data/tests/test_ssl_args.rb +1 -1
- data/tests/test_ssl_methods.rb +1 -1
- data/tests/test_ssl_verify.rb +82 -0
- data/tests/test_timers.rb +81 -88
- data/tests/test_ud.rb +0 -7
- data/tests/testem.rb +1 -1
- metadata +52 -36
- data/lib/em/eventable.rb +0 -39
- data/lib/eventmachine_version.rb +0 -31
- data/lib/protocols/header_and_content.rb +0 -129
- data/lib/protocols/httpcli2.rb +0 -803
- data/lib/protocols/httpclient.rb +0 -270
- data/lib/protocols/linetext2.rb +0 -161
- data/lib/protocols/postgres.rb +0 -261
- data/lib/protocols/saslauth.rb +0 -179
- data/lib/protocols/smtpclient.rb +0 -308
- data/lib/protocols/smtpserver.rb +0 -556
- data/lib/protocols/stomp.rb +0 -153
- data/tests/test_eventables.rb +0 -77
data/tests/test_next_tick.rb
CHANGED
|
@@ -29,81 +29,107 @@ $:.unshift "../lib"
|
|
|
29
29
|
require 'eventmachine'
|
|
30
30
|
require 'test/unit'
|
|
31
31
|
|
|
32
|
+
class TestNextTick < Test::Unit::TestCase
|
|
32
33
|
|
|
34
|
+
def test_tick_arg
|
|
35
|
+
pr = proc {EM.stop}
|
|
36
|
+
EM.epoll
|
|
37
|
+
EM.run {
|
|
38
|
+
EM.next_tick pr
|
|
39
|
+
}
|
|
40
|
+
assert true
|
|
41
|
+
end
|
|
33
42
|
|
|
34
|
-
|
|
43
|
+
def test_tick_block
|
|
44
|
+
EM.epoll
|
|
45
|
+
EM.run {
|
|
46
|
+
EM.next_tick {EM.stop}
|
|
47
|
+
}
|
|
48
|
+
assert true
|
|
49
|
+
end
|
|
35
50
|
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
# This illustrates the solution to a long-standing problem.
|
|
52
|
+
# It's now possible to correctly nest calls to EM#run.
|
|
53
|
+
# See the source code commentary for EM#run for more info.
|
|
54
|
+
#
|
|
55
|
+
def test_run_run
|
|
56
|
+
EM.run {
|
|
57
|
+
EM.run {
|
|
58
|
+
EM.next_tick {EM.stop}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
end
|
|
38
62
|
|
|
39
|
-
|
|
40
|
-
|
|
63
|
+
def test_pre_run_queue
|
|
64
|
+
x = false
|
|
65
|
+
EM.next_tick { EM.stop; x = true }
|
|
66
|
+
EM.run { EM.add_timer(0.2) { EM.stop } }
|
|
67
|
+
assert x
|
|
68
|
+
end
|
|
41
69
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
70
|
+
def test_cleanup_after_stop
|
|
71
|
+
x = true
|
|
72
|
+
EM.run{
|
|
73
|
+
EM.next_tick{
|
|
74
|
+
EM.stop
|
|
75
|
+
EM.next_tick{ x=false }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
EM.run{
|
|
79
|
+
EM.next_tick{ EM.stop }
|
|
80
|
+
}
|
|
81
|
+
assert x
|
|
82
|
+
end
|
|
50
83
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
84
|
+
# We now support an additional parameter for EM#run.
|
|
85
|
+
# You can pass two procs to EM#run now. The first is executed as the normal
|
|
86
|
+
# run block. The second (if given) is scheduled for execution after the
|
|
87
|
+
# reactor loop completes.
|
|
88
|
+
# The reason for supporting this is subtle. There has always been an expectation
|
|
89
|
+
# that EM#run doesn't return until after the reactor loop ends. But now it's
|
|
90
|
+
# possible to nest calls to EM#run, which means that a nested call WILL
|
|
91
|
+
# RETURN. In order to write code that will run correctly either way, it's
|
|
92
|
+
# recommended to put any code which must execute after the reactor completes
|
|
93
|
+
# in the second parameter.
|
|
94
|
+
#
|
|
95
|
+
def test_run_run_2
|
|
96
|
+
a = proc {EM.stop}
|
|
97
|
+
b = proc {assert true}
|
|
98
|
+
EM.run a, b
|
|
99
|
+
end
|
|
58
100
|
|
|
59
|
-
# This illustrates the solution to a long-standing problem.
|
|
60
|
-
# It's now possible to correctly nest calls to EM#run.
|
|
61
|
-
# See the source code commentary for EM#run for more info.
|
|
62
|
-
#
|
|
63
|
-
def test_run_run
|
|
64
|
-
EM.run {
|
|
65
|
-
EM.run {
|
|
66
|
-
EM.next_tick {EM.stop}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
end
|
|
70
101
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
102
|
+
# This illustrates that EM#run returns when it's called nested.
|
|
103
|
+
# This isn't a feature, rather it's something to be wary of when writing code
|
|
104
|
+
# that must run correctly even if EM#run is called while a reactor is already
|
|
105
|
+
# running.
|
|
106
|
+
def test_run_run_3
|
|
107
|
+
a = []
|
|
108
|
+
EM.run {
|
|
109
|
+
EM.run proc {EM.stop}, proc {a << 2}
|
|
110
|
+
a << 1
|
|
111
|
+
}
|
|
112
|
+
assert_equal( [1,2], a )
|
|
113
|
+
end
|
|
77
114
|
|
|
78
|
-
# We now support an additional parameter for EM#run.
|
|
79
|
-
# You can pass two procs to EM#run now. The first is executed as the normal
|
|
80
|
-
# run block. The second (if given) is scheduled for execution after the
|
|
81
|
-
# reactor loop completes.
|
|
82
|
-
# The reason for supporting this is subtle. There has always been an expectation
|
|
83
|
-
# that EM#run doesn't return until after the reactor loop ends. But now it's
|
|
84
|
-
# possible to nest calls to EM#run, which means that a nested call WILL
|
|
85
|
-
# RETURN. In order to write code that will run correctly either way, it's
|
|
86
|
-
# recommended to put any code which must execute after the reactor completes
|
|
87
|
-
# in the second parameter.
|
|
88
|
-
#
|
|
89
|
-
def test_run_run_2
|
|
90
|
-
a = proc {EM.stop}
|
|
91
|
-
b = proc {assert true}
|
|
92
|
-
EM.run a, b
|
|
93
|
-
end
|
|
94
115
|
|
|
116
|
+
def test_schedule_on_reactor_thread
|
|
117
|
+
x = false
|
|
118
|
+
EM.run do
|
|
119
|
+
EM.schedule { x = true }
|
|
120
|
+
EM.stop
|
|
121
|
+
end
|
|
122
|
+
assert x
|
|
123
|
+
end
|
|
95
124
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
assert_equal( [1,2], a )
|
|
107
|
-
end
|
|
125
|
+
def test_schedule_from_thread
|
|
126
|
+
x = false
|
|
127
|
+
EM.run do
|
|
128
|
+
Thread.new { EM.schedule { x = true } }.join
|
|
129
|
+
assert !x
|
|
130
|
+
EM.next_tick { EM.stop }
|
|
131
|
+
end
|
|
132
|
+
assert x
|
|
133
|
+
end
|
|
108
134
|
|
|
109
135
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
$:.unshift "../lib"
|
|
2
|
+
require 'eventmachine'
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
|
|
5
|
+
class TestObjectProtocol < Test::Unit::TestCase
|
|
6
|
+
Host = "127.0.0.1"
|
|
7
|
+
Port = 9550
|
|
8
|
+
|
|
9
|
+
module Server
|
|
10
|
+
include EM::P::ObjectProtocol
|
|
11
|
+
def post_init
|
|
12
|
+
send_object :hello=>'world'
|
|
13
|
+
end
|
|
14
|
+
def receive_object obj
|
|
15
|
+
$server = obj
|
|
16
|
+
EM.stop
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
module Client
|
|
21
|
+
include EM::P::ObjectProtocol
|
|
22
|
+
def receive_object obj
|
|
23
|
+
$client = obj
|
|
24
|
+
send_object 'you_said'=>obj
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_send_receive
|
|
29
|
+
EM.run{
|
|
30
|
+
EM.start_server Host, Port, Server
|
|
31
|
+
EM.connect Host, Port, Client
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
assert($client == {:hello=>'world'})
|
|
35
|
+
assert($server == {'you_said'=>{:hello=>'world'}})
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
$:.unshift "../lib"
|
|
2
|
+
require 'eventmachine'
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
|
|
5
|
+
class TestProcessWatch < Test::Unit::TestCase
|
|
6
|
+
module ParentProcessWatcher
|
|
7
|
+
def process_forked
|
|
8
|
+
$forked = true
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module ChildProcessWatcher
|
|
13
|
+
def process_exited
|
|
14
|
+
$exited = true
|
|
15
|
+
end
|
|
16
|
+
def unbind
|
|
17
|
+
$unbind = true
|
|
18
|
+
EM.stop
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def setup
|
|
23
|
+
EM.kqueue = true if EM.kqueue?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def teardown
|
|
27
|
+
EM.kqueue = false if EM.kqueue?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_events
|
|
31
|
+
EM.run{
|
|
32
|
+
# watch ourselves for a fork notification
|
|
33
|
+
EM.watch_process(Process.pid, ParentProcessWatcher)
|
|
34
|
+
$fork_pid = fork{ sleep }
|
|
35
|
+
child = EM.watch_process($fork_pid, ChildProcessWatcher)
|
|
36
|
+
$pid = child.pid
|
|
37
|
+
|
|
38
|
+
EM.add_timer(0.5){
|
|
39
|
+
Process.kill('TERM', $fork_pid)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
assert_equal($pid, $fork_pid)
|
|
44
|
+
assert($forked)
|
|
45
|
+
assert($exited)
|
|
46
|
+
assert($unbind)
|
|
47
|
+
end
|
|
48
|
+
end
|
data/tests/test_processes.rb
CHANGED
|
@@ -30,27 +30,27 @@ require 'test/unit'
|
|
|
30
30
|
|
|
31
31
|
class TestProcesses < Test::Unit::TestCase
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
33
|
+
# EM::DeferrableChildProcess is a sugaring of a common use-case
|
|
34
|
+
# involving EM::popen.
|
|
35
|
+
# Call the #open method on EM::DeferrableChildProcess, passing
|
|
36
|
+
# a command-string. #open immediately returns an EM::Deferrable
|
|
37
|
+
# object. It also schedules the forking of a child process, which
|
|
38
|
+
# will execute the command passed to #open.
|
|
39
|
+
# When the forked child terminates, the Deferrable will be signalled
|
|
40
|
+
# and execute its callbacks, passing the data that the child process
|
|
41
|
+
# wrote to stdout.
|
|
42
|
+
#
|
|
43
|
+
def test_deferrable_child_process
|
|
44
|
+
ls = ""
|
|
45
|
+
EM.run {
|
|
46
|
+
d = EM::DeferrableChildProcess.open( "ls -ltr" )
|
|
47
|
+
d.callback {|data_from_child|
|
|
48
|
+
ls = data_from_child
|
|
49
|
+
EM.stop
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
assert( ls.length > 0)
|
|
53
|
+
end
|
|
54
54
|
|
|
55
55
|
def setup
|
|
56
56
|
$out = nil
|
|
@@ -67,6 +67,16 @@ class TestProcesses < Test::Unit::TestCase
|
|
|
67
67
|
assert_equal($status.class, Process::Status)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
+
def test_em_system_pid
|
|
71
|
+
$pids = []
|
|
72
|
+
|
|
73
|
+
EM.run{
|
|
74
|
+
$pids << EM.system('echo hi', proc{ |out,status|$pids << status.pid; EM.stop })
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
assert_equal $pids[0], $pids[1]
|
|
78
|
+
end
|
|
79
|
+
|
|
70
80
|
def test_em_system_with_proc
|
|
71
81
|
EM.run{
|
|
72
82
|
EM.system('ls', proc{ |out,status| $out, $status = out, status; EM.stop })
|
|
@@ -89,7 +99,30 @@ class TestProcesses < Test::Unit::TestCase
|
|
|
89
99
|
})
|
|
90
100
|
}
|
|
91
101
|
|
|
92
|
-
assert_equal(
|
|
102
|
+
assert_equal("hello\n", $out)
|
|
93
103
|
end
|
|
94
|
-
end
|
|
95
104
|
|
|
105
|
+
def test_em_system_cmd_arguments
|
|
106
|
+
EM.run{
|
|
107
|
+
EM.system('sh', '--version', proc{ |process|
|
|
108
|
+
}, proc{ |out,status|
|
|
109
|
+
$out = out
|
|
110
|
+
$status = status
|
|
111
|
+
EM.stop
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
assert_match(/version/i, $out)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_em_system_spaced_arguments
|
|
119
|
+
EM.run{
|
|
120
|
+
EM.system('ruby', '-e', 'puts "hello"', proc{ |out,status|
|
|
121
|
+
$out = out
|
|
122
|
+
EM.stop
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
assert_equal("hello\n", $out)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
$:.unshift "../lib"
|
|
2
|
+
require 'eventmachine'
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
|
|
5
|
+
class TestProxyConnection < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
module ProxyConnection
|
|
8
|
+
def initialize(client, request)
|
|
9
|
+
@client, @request = client, request
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def post_init
|
|
13
|
+
EM::enable_proxy(self, @client)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def connection_completed
|
|
17
|
+
EM.next_tick {
|
|
18
|
+
send_data @request
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def proxy_target_unbound
|
|
23
|
+
$unbound_early = true
|
|
24
|
+
EM.stop
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def unbind
|
|
28
|
+
@client.close_connection_after_writing
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module Client
|
|
33
|
+
def connection_completed
|
|
34
|
+
send_data "EventMachine rocks!"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def receive_data(data)
|
|
38
|
+
$client_data = data
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def unbind
|
|
42
|
+
EM.stop
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
module Client2
|
|
47
|
+
include Client
|
|
48
|
+
def unbind; end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
module Server
|
|
52
|
+
def receive_data(data)
|
|
53
|
+
send_data "I know!" if data == "EventMachine rocks!"
|
|
54
|
+
close_connection_after_writing
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
module ProxyServer
|
|
59
|
+
def receive_data(data)
|
|
60
|
+
EM.connect("127.0.0.1", 54321, ProxyConnection, self, data)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module EarlyClosingProxy
|
|
65
|
+
def receive_data(data)
|
|
66
|
+
EM.connect("127.0.0.1", 54321, ProxyConnection, self, data)
|
|
67
|
+
close_connection
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_proxy_connection
|
|
72
|
+
EM.run {
|
|
73
|
+
EM.start_server("127.0.0.1", 54321, Server)
|
|
74
|
+
EM.start_server("127.0.0.1", 12345, ProxyServer)
|
|
75
|
+
EM.connect("127.0.0.1", 12345, Client)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
assert_equal("I know!", $client_data)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_early_close
|
|
82
|
+
$client_data = nil
|
|
83
|
+
EM.run {
|
|
84
|
+
EM.start_server("127.0.0.1", 54321, Server)
|
|
85
|
+
EM.start_server("127.0.0.1", 12345, EarlyClosingProxy)
|
|
86
|
+
EM.connect("127.0.0.1", 12345, Client2)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
assert($unbound_early)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|