eventmachine 0.12.6 → 0.12.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/{docs/README → README} +21 -13
  2. data/Rakefile +14 -4
  3. data/docs/DEFERRABLES +0 -5
  4. data/docs/INSTALL +2 -4
  5. data/docs/LEGAL +1 -1
  6. data/docs/LIGHTWEIGHT_CONCURRENCY +0 -2
  7. data/docs/PURE_RUBY +0 -2
  8. data/docs/RELEASE_NOTES +0 -2
  9. data/docs/SMTP +0 -7
  10. data/docs/SPAWNED_PROCESSES +0 -4
  11. data/docs/TODO +0 -2
  12. data/eventmachine.gemspec +17 -8
  13. data/examples/ex_channel.rb +43 -0
  14. data/examples/ex_queue.rb +2 -0
  15. data/examples/helper.rb +2 -0
  16. data/ext/cmain.cpp +119 -20
  17. data/ext/cplusplus.cpp +15 -6
  18. data/ext/ed.cpp +303 -93
  19. data/ext/ed.h +49 -22
  20. data/ext/em.cpp +368 -42
  21. data/ext/em.h +43 -6
  22. data/ext/eventmachine.h +21 -8
  23. data/ext/eventmachine_cpp.h +1 -0
  24. data/ext/extconf.rb +4 -0
  25. data/ext/kb.cpp +1 -2
  26. data/ext/pipe.cpp +1 -3
  27. data/ext/project.h +21 -0
  28. data/ext/rubymain.cpp +232 -32
  29. data/ext/ssl.cpp +38 -1
  30. data/ext/ssl.h +5 -1
  31. data/java/src/com/rubyeventmachine/Application.java +7 -3
  32. data/java/src/com/rubyeventmachine/EmReactor.java +16 -1
  33. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +25 -3
  34. data/lib/{protocols → em}/buftok.rb +16 -5
  35. data/lib/em/callback.rb +26 -0
  36. data/lib/em/channel.rb +57 -0
  37. data/lib/em/connection.rb +505 -0
  38. data/lib/em/deferrable.rb +144 -165
  39. data/lib/em/file_watch.rb +54 -0
  40. data/lib/em/future.rb +24 -25
  41. data/lib/em/messages.rb +1 -1
  42. data/lib/em/process_watch.rb +44 -0
  43. data/lib/em/processes.rb +58 -52
  44. data/lib/em/protocols.rb +35 -0
  45. data/lib/em/protocols/header_and_content.rb +138 -0
  46. data/lib/em/protocols/httpclient.rb +263 -0
  47. data/lib/em/protocols/httpclient2.rb +582 -0
  48. data/lib/{protocols → em/protocols}/line_and_text.rb +2 -2
  49. data/lib/em/protocols/linetext2.rb +160 -0
  50. data/lib/{protocols → em/protocols}/memcache.rb +37 -7
  51. data/lib/em/protocols/object_protocol.rb +39 -0
  52. data/lib/em/protocols/postgres3.rb +247 -0
  53. data/lib/em/protocols/saslauth.rb +175 -0
  54. data/lib/em/protocols/smtpclient.rb +331 -0
  55. data/lib/em/protocols/smtpserver.rb +547 -0
  56. data/lib/em/protocols/stomp.rb +200 -0
  57. data/lib/{protocols → em/protocols}/tcptest.rb +21 -25
  58. data/lib/em/queue.rb +61 -0
  59. data/lib/em/spawnable.rb +53 -56
  60. data/lib/em/streamer.rb +92 -74
  61. data/lib/em/timers.rb +55 -0
  62. data/lib/em/version.rb +3 -0
  63. data/lib/eventmachine.rb +1008 -1298
  64. data/lib/evma.rb +1 -1
  65. data/lib/jeventmachine.rb +106 -101
  66. data/lib/pr_eventmachine.rb +47 -36
  67. data/tasks/project.rake +2 -1
  68. data/tests/client.crt +31 -0
  69. data/tests/client.key +51 -0
  70. data/tests/test_attach.rb +18 -0
  71. data/tests/test_basic.rb +108 -54
  72. data/tests/test_channel.rb +63 -0
  73. data/tests/test_connection_count.rb +2 -2
  74. data/tests/test_epoll.rb +109 -110
  75. data/tests/test_errors.rb +36 -36
  76. data/tests/test_exc.rb +22 -25
  77. data/tests/test_file_watch.rb +49 -0
  78. data/tests/test_futures.rb +77 -93
  79. data/tests/test_hc.rb +2 -2
  80. data/tests/test_httpclient.rb +55 -52
  81. data/tests/test_httpclient2.rb +110 -112
  82. data/tests/test_inactivity_timeout.rb +30 -0
  83. data/tests/test_kb.rb +8 -9
  84. data/tests/test_ltp2.rb +274 -277
  85. data/tests/test_next_tick.rb +91 -65
  86. data/tests/test_object_protocol.rb +37 -0
  87. data/tests/test_process_watch.rb +48 -0
  88. data/tests/test_processes.rb +56 -23
  89. data/tests/test_proxy_connection.rb +92 -0
  90. data/tests/test_pure.rb +1 -5
  91. data/tests/test_queue.rb +44 -0
  92. data/tests/test_running.rb +9 -14
  93. data/tests/test_sasl.rb +32 -34
  94. data/tests/test_send_file.rb +175 -176
  95. data/tests/test_servers.rb +37 -41
  96. data/tests/test_smtpserver.rb +47 -55
  97. data/tests/test_spawn.rb +284 -291
  98. data/tests/test_ssl_args.rb +1 -1
  99. data/tests/test_ssl_methods.rb +1 -1
  100. data/tests/test_ssl_verify.rb +82 -0
  101. data/tests/test_timers.rb +81 -88
  102. data/tests/test_ud.rb +0 -7
  103. data/tests/testem.rb +1 -1
  104. metadata +68 -39
  105. data/lib/em/eventable.rb +0 -39
  106. data/lib/eventmachine_version.rb +0 -31
  107. data/lib/protocols/header_and_content.rb +0 -129
  108. data/lib/protocols/httpcli2.rb +0 -803
  109. data/lib/protocols/httpclient.rb +0 -270
  110. data/lib/protocols/linetext2.rb +0 -161
  111. data/lib/protocols/postgres.rb +0 -261
  112. data/lib/protocols/saslauth.rb +0 -179
  113. data/lib/protocols/smtpclient.rb +0 -308
  114. data/lib/protocols/smtpserver.rb +0 -556
  115. data/lib/protocols/stomp.rb +0 -153
  116. data/tests/test_eventables.rb +0 -77
@@ -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
- class TestNextTick < Test::Unit::TestCase
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
- def setup
37
- end
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
- def teardown
40
- end
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
- def test_tick_arg
43
- pr = proc {EM.stop}
44
- EM.epoll
45
- EM.run {
46
- EM.next_tick pr
47
- }
48
- assert true
49
- end
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
- def test_tick_block
52
- EM.epoll
53
- EM.run {
54
- EM.next_tick {EM.stop}
55
- }
56
- assert true
57
- end
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
- def test_pre_run_queue
72
- x = false
73
- EM.next_tick { EM.stop; x = true }
74
- EM.run { EM.add_timer(0.2) { EM.stop } }
75
- assert x
76
- end
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
- # This illustrates that EM#run returns when it's called nested.
97
- # This isn't a feature, rather it's something to be wary of when writing code
98
- # that must run correctly even if EM#run is called while a reactor is already
99
- # running.
100
- def test_run_run_3
101
- a = []
102
- EM.run {
103
- EM.run proc {EM.stop}, proc {a << 2}
104
- a << 1
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
@@ -30,27 +30,27 @@ require 'test/unit'
30
30
 
31
31
  class TestProcesses < Test::Unit::TestCase
32
32
 
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
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($out, "hello\n")
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