eventmachine 0.12.10 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +1 -0
  3. data/README +1 -2
  4. data/Rakefile +4 -76
  5. data/docs/DEFERRABLES +183 -70
  6. data/docs/KEYBOARD +15 -11
  7. data/docs/LIGHTWEIGHT_CONCURRENCY +84 -24
  8. data/docs/SMTP +3 -1
  9. data/docs/SPAWNED_PROCESSES +84 -25
  10. data/eventmachine.gemspec +19 -26
  11. data/examples/ex_tick_loop_array.rb +15 -0
  12. data/examples/ex_tick_loop_counter.rb +32 -0
  13. data/ext/binder.cpp +0 -1
  14. data/ext/cmain.cpp +36 -11
  15. data/ext/cplusplus.cpp +1 -1
  16. data/ext/ed.cpp +104 -113
  17. data/ext/ed.h +24 -30
  18. data/ext/em.cpp +347 -248
  19. data/ext/em.h +23 -16
  20. data/ext/eventmachine.h +5 -3
  21. data/ext/extconf.rb +5 -3
  22. data/ext/fastfilereader/extconf.rb +5 -3
  23. data/ext/fastfilereader/mapper.cpp +1 -1
  24. data/ext/kb.cpp +1 -3
  25. data/ext/pipe.cpp +9 -11
  26. data/ext/project.h +12 -4
  27. data/ext/rubymain.cpp +138 -89
  28. data/java/src/com/rubyeventmachine/EmReactor.java +1 -0
  29. data/lib/em/channel.rb +1 -1
  30. data/lib/em/connection.rb +6 -1
  31. data/lib/em/deferrable.rb +16 -2
  32. data/lib/em/iterator.rb +270 -0
  33. data/lib/em/protocols.rb +1 -1
  34. data/lib/em/protocols/httpclient.rb +5 -0
  35. data/lib/em/protocols/line_protocol.rb +28 -0
  36. data/lib/em/protocols/smtpserver.rb +101 -8
  37. data/lib/em/protocols/stomp.rb +1 -1
  38. data/lib/{pr_eventmachine.rb → em/pure_ruby.rb} +1 -11
  39. data/lib/em/queue.rb +1 -0
  40. data/lib/em/streamer.rb +1 -1
  41. data/lib/em/tick_loop.rb +85 -0
  42. data/lib/em/timers.rb +2 -1
  43. data/lib/em/version.rb +1 -1
  44. data/lib/eventmachine.rb +38 -84
  45. data/lib/jeventmachine.rb +1 -0
  46. data/tests/test_attach.rb +13 -3
  47. data/tests/test_basic.rb +60 -95
  48. data/tests/test_channel.rb +3 -2
  49. data/tests/test_defer.rb +14 -12
  50. data/tests/test_deferrable.rb +35 -0
  51. data/tests/test_file_watch.rb +1 -1
  52. data/tests/test_futures.rb +1 -1
  53. data/tests/test_hc.rb +40 -68
  54. data/tests/test_httpclient.rb +15 -6
  55. data/tests/test_httpclient2.rb +3 -2
  56. data/tests/test_inactivity_timeout.rb +3 -3
  57. data/tests/test_ltp.rb +13 -5
  58. data/tests/test_next_tick.rb +1 -1
  59. data/tests/test_pending_connect_timeout.rb +2 -2
  60. data/tests/test_process_watch.rb +36 -34
  61. data/tests/test_proxy_connection.rb +52 -0
  62. data/tests/test_pure.rb +10 -1
  63. data/tests/test_sasl.rb +1 -1
  64. data/tests/test_send_file.rb +16 -7
  65. data/tests/test_servers.rb +1 -1
  66. data/tests/test_tick_loop.rb +59 -0
  67. data/tests/test_timers.rb +13 -15
  68. metadata +45 -17
  69. data/web/whatis +0 -7
@@ -30,8 +30,9 @@ class TestEventMachineChannel < Test::Unit::TestCase
30
30
  EM.run do
31
31
  c = EM::Channel.new
32
32
  c.pop{ |v| s = v }
33
- c << 1
34
- c << 2
33
+ c.push(1,2,3)
34
+ c << 4
35
+ c << 5
35
36
  EM.next_tick { EM.stop }
36
37
  end
37
38
  assert_equal 1, s
@@ -28,20 +28,22 @@ $:.unshift "../lib"
28
28
  require 'eventmachine'
29
29
  require 'test/unit'
30
30
 
31
- class TestDeferUsage < Test::Unit::TestCase
31
+ unless RUBY_VERSION >= '1.9.0'
32
+ class TestDeferUsage < Test::Unit::TestCase
32
33
 
33
- def test_defers
34
- n = 0
35
- n_times = 20
36
- EM.run {
37
- n_times.times {
38
- work_proc = proc { n += 1 }
39
- callback = proc { EM.stop if n == n_times }
40
- EM.defer work_proc, callback
34
+ def test_defers
35
+ n = 0
36
+ n_times = 20
37
+ EM.run {
38
+ n_times.times {
39
+ work_proc = proc { n += 1 }
40
+ callback = proc { EM.stop if n == n_times }
41
+ EM.defer work_proc, callback
42
+ }
41
43
  }
42
- }
43
- assert_equal( n, n_times )
44
- end unless RUBY_VERSION >= '1.9.0'
44
+ assert_equal( n, n_times )
45
+ end
45
46
 
47
+ end
46
48
  end
47
49
 
@@ -0,0 +1,35 @@
1
+ $:.unshift "../lib"
2
+ require 'eventmachine'
3
+ require 'test/unit'
4
+
5
+ class TestDeferrable < Test::Unit::TestCase
6
+ class Later
7
+ include EM::Deferrable
8
+ end
9
+
10
+ def test_timeout_without_args
11
+ $args = "unset"
12
+
13
+ EM.run {
14
+ df = Later.new
15
+ df.timeout(0.2)
16
+ df.errback { $args = "none" }
17
+ EM.add_timer(0.5) { EM.stop }
18
+ }
19
+
20
+ assert_equal("none", $args)
21
+ end
22
+
23
+ def test_timeout_with_args
24
+ $args = "unset"
25
+
26
+ EM.run {
27
+ df = Later.new
28
+ df.timeout(0.2, :timeout, :foo)
29
+ df.errback { |type, name| $args = [type, name] }
30
+ EM.add_timer(0.5) { EM.stop }
31
+ }
32
+
33
+ assert_equal([:timeout, :foo], $args)
34
+ end
35
+ end
@@ -38,7 +38,7 @@ class TestFileWatch < Test::Unit::TestCase
38
38
  File.open(file.path, 'w'){ |f| f.puts 'hi' }
39
39
 
40
40
  # delete it
41
- EM.add_timer(0.25){ file.close; file.delete }
41
+ EM.add_timer(0.01){ file.close; file.delete }
42
42
  }
43
43
 
44
44
  assert_equal($path, $tmp_path)
@@ -190,7 +190,7 @@ class TestFutures < Test::Unit::TestCase
190
190
  d = EM::DefaultDeferrable.new
191
191
  d.callback {n = 1; EM.stop}
192
192
  d.errback {n = 2; EM.stop}
193
- d.timeout(1)
193
+ d.timeout(0.01)
194
194
  }
195
195
  assert_equal( 2, n )
196
196
  end
@@ -24,7 +24,6 @@
24
24
  #
25
25
  #
26
26
 
27
- # $:.unshift "../lib"
28
27
  require 'eventmachine'
29
28
  require 'test/unit'
30
29
 
@@ -49,27 +48,25 @@ class TestHeaderAndContentProtocol < Test::Unit::TestCase
49
48
  @request << [hdrs, content]
50
49
  end
51
50
  end
51
+
52
+ class StopOnUnbind < EM::Connection
53
+ def unbind
54
+ EM.add_timer(0.1) { EM.stop }
55
+ end
56
+ end
52
57
 
53
58
  def test_no_content
54
59
  the_connection = nil
55
- EventMachine.run {
56
- EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
60
+ EM.run {
61
+ EM.start_server( TestHost, TestPort, SimpleTest ) do |conn|
57
62
  the_connection = conn
58
63
  end
59
- EventMachine.add_timer(4) {raise "test timed out"}
64
+ setup_timeout
60
65
 
61
- client = Module.new do
62
- def unbind
63
- EM.add_timer(0.1) { EM.stop }
64
- end
65
-
66
- def post_init
67
- send_data [ "aaa\n", "bbb\r\n", "ccc\n", "\n" ].join
68
- close_connection_after_writing
69
- end
66
+ EM.connect TestHost, TestPort, StopOnUnbind do |c|
67
+ c.send_data [ "aaa\n", "bbb\r\n", "ccc\n", "\n" ].join
68
+ c.close_connection_after_writing
70
69
  end
71
-
72
- EventMachine.connect( TestHost, TestPort, client )
73
70
  }
74
71
  assert_equal( ["aaa"], the_connection.first_header )
75
72
  assert_equal( [%w(aaa bbb ccc)], the_connection.my_headers )
@@ -84,26 +81,14 @@ class TestHeaderAndContentProtocol < Test::Unit::TestCase
84
81
  EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
85
82
  the_connection = conn
86
83
  end
87
- EventMachine.add_timer(4) { assert(false, 'test timeout'); EM.stop }
88
-
89
- client = Module.new do
90
- define_method(:headers) { headers }
91
- define_method(:content) { content }
92
-
93
- def unbind
94
- EM.add_timer(0.1) { EM.stop }
95
- end
84
+ setup_timeout
96
85
 
97
- def post_init
98
- headers.each { |h| send_data "#{h}\r\n" }
99
- send_data "\n"
100
- send_data content
101
- close_connection_after_writing
102
- end
86
+ EM.connect TestHost, TestPort, StopOnUnbind do |c|
87
+ headers.each { |h| c.send_data "#{h}\r\n" }
88
+ c.send_data "\n"
89
+ c.send_data content
90
+ c.close_connection_after_writing
103
91
  end
104
-
105
- EventMachine.connect( TestHost, TestPort, client )
106
-
107
92
  }
108
93
  assert_equal( ["aaa"], the_connection.first_header )
109
94
  assert_equal( [headers], the_connection.my_headers )
@@ -118,27 +103,16 @@ class TestHeaderAndContentProtocol < Test::Unit::TestCase
118
103
  EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
119
104
  the_connection = conn
120
105
  end
121
- EventMachine.add_timer(4) { assert(false, 'test timeout'); EM.stop }
122
-
123
- client = Module.new do
124
- define_method(:headers) { headers }
125
- define_method(:content) { content }
126
-
127
- def unbind
128
- EM.add_timer(0.1) { EM.stop }
129
- end
106
+ setup_timeout
130
107
 
131
- def post_init
132
- 5.times do
133
- headers.each { |h| send_data "#{h}\r\n" }
134
- send_data "\n"
135
- send_data content
136
- end
137
- close_connection_after_writing
108
+ EventMachine.connect( TestHost, TestPort, StopOnUnbind ) do |c|
109
+ 5.times do
110
+ headers.each { |h| c.send_data "#{h}\r\n" }
111
+ c.send_data "\n"
112
+ c.send_data content
138
113
  end
114
+ c.close_connection_after_writing
139
115
  end
140
-
141
- EventMachine.connect( TestHost, TestPort, client )
142
116
  }
143
117
  assert_equal( ["aaa"] * 5, the_connection.first_header )
144
118
  assert_equal( [headers] * 5, the_connection.my_headers )
@@ -184,25 +158,14 @@ class TestHeaderAndContentProtocol < Test::Unit::TestCase
184
158
  EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
185
159
  the_connection = conn
186
160
  end
187
- EventMachine.add_timer(4) {raise "test timed out"}
188
-
189
- client = Module.new do
190
- define_method(:headers) { headers }
191
- define_method(:content) { content }
161
+ setup_timeout
192
162
 
193
- def unbind
194
- EM.add_timer(0.1) { EM.stop }
195
- end
196
-
197
- def post_init
198
- headers.each { |h| send_data "#{h}\r\n" }
199
- send_data "\n"
200
- send_data content
201
- close_connection_after_writing
202
- end
163
+ EventMachine.connect( TestHost, TestPort, StopOnUnbind ) do |c|
164
+ headers.each { |h| c.send_data "#{h}\r\n" }
165
+ c.send_data "\n"
166
+ c.send_data content
167
+ c.close_connection_after_writing
203
168
  end
204
-
205
- EventMachine.connect( TestHost, TestPort, client )
206
169
  }
207
170
 
208
171
  hsh = the_connection.headers_2_hash( the_connection.my_headers.shift )
@@ -215,4 +178,13 @@ class TestHeaderAndContentProtocol < Test::Unit::TestCase
215
178
  assert_equal(expect, hsh)
216
179
  end
217
180
 
181
+ def setup_timeout(timeout = 4)
182
+ EM.schedule {
183
+ start_time = EM.current_time
184
+ EM.add_periodic_timer(0.01) {
185
+ raise "timeout" if EM.current_time - start_time >= timeout
186
+ }
187
+ }
188
+ end
189
+
218
190
  end
@@ -44,7 +44,7 @@ class TestHttpClient < Test::Unit::TestCase
44
44
  def test_http_client
45
45
  ok = false
46
46
  EventMachine.run {
47
- c = EventMachine::Protocols::HttpClient.send :request, :host => "www.bayshorenetworks.com", :port => 80
47
+ c = EventMachine::Protocols::HttpClient.send :request, :host => "www.google.com", :port => 80
48
48
  c.callback {
49
49
  ok = true
50
50
  EventMachine.stop
@@ -59,7 +59,7 @@ class TestHttpClient < Test::Unit::TestCase
59
59
  def test_http_client_1
60
60
  ok = false
61
61
  EventMachine.run {
62
- c = EventMachine::Protocols::HttpClient.send :request, :host => "www.bayshorenetworks.com", :port => 80
62
+ c = EventMachine::Protocols::HttpClient.send :request, :host => "www.google.com", :port => 80
63
63
  c.callback {ok = true; EventMachine.stop}
64
64
  c.errback {EventMachine.stop}
65
65
  }
@@ -71,7 +71,7 @@ class TestHttpClient < Test::Unit::TestCase
71
71
  def test_http_client_2
72
72
  ok = false
73
73
  EventMachine.run {
74
- c = EventMachine::Protocols::HttpClient.send :request, :host => "www.bayshorenetworks.com", :port => 80
74
+ c = EventMachine::Protocols::HttpClient.send :request, :host => "www.google.com", :port => 80
75
75
  c.callback {|result|
76
76
  ok = true;
77
77
  EventMachine.stop
@@ -154,6 +154,15 @@ class TestHttpClient < Test::Unit::TestCase
154
154
  close_connection_after_writing
155
155
  end
156
156
  end
157
+
158
+ def setup_timeout(timeout = 4)
159
+ EM.schedule {
160
+ start_time = EM.current_time
161
+ EM.add_periodic_timer(0.01) {
162
+ raise "timeout" if EM.current_time - start_time >= timeout
163
+ }
164
+ }
165
+ end
157
166
 
158
167
  # TODO, this is WRONG. The handler is asserting an HTTP 1.1 request, but the client
159
168
  # is sending a 1.0 request. Gotta fix the client
@@ -161,7 +170,7 @@ class TestHttpClient < Test::Unit::TestCase
161
170
  response = nil
162
171
  EventMachine.run {
163
172
  EventMachine.start_server Localhost, Localport, PostContent
164
- EventMachine.add_timer(2) {raise "timed out"}
173
+ setup_timeout(2)
165
174
  c = EventMachine::Protocols::HttpClient.request(
166
175
  :host=>Localhost,
167
176
  :port=>Localport,
@@ -186,7 +195,7 @@ class TestHttpClient < Test::Unit::TestCase
186
195
  def test_cookie
187
196
  ok = false
188
197
  EM.run {
189
- c = EM::Protocols::HttpClient.send :request, :host => "www.bayshorenetworks.com", :port => 80, :cookie=>"aaa=bbb"
198
+ c = EM::Protocols::HttpClient.send :request, :host => "www.google.com", :port => 80, :cookie=>"aaa=bbb"
190
199
  c.callback {|result|
191
200
  ok = true;
192
201
  EventMachine.stop
@@ -202,7 +211,7 @@ class TestHttpClient < Test::Unit::TestCase
202
211
  ok = false
203
212
  EM.run {
204
213
  c = EM::P::HttpClient.request(
205
- :host => "www.bayshorenetworks.com",
214
+ :host => "www.google.com",
206
215
  :port => 80,
207
216
  :version => "1.0"
208
217
  )
@@ -121,7 +121,8 @@ class TestHttpClient2 < Test::Unit::TestCase
121
121
  e.callback {
122
122
  headers2 = e.headers
123
123
  }
124
- EM::Timer.new(1) {EM.stop}
124
+ EM.tick_loop { EM.stop if headers && headers2 }
125
+ EM.add_timer(1) { EM.stop }
125
126
  }
126
127
  assert(headers)
127
128
  assert(headers2)
@@ -141,7 +142,7 @@ class TestHttpClient2 < Test::Unit::TestCase
141
142
  def test_https_get
142
143
  d = nil
143
144
  EM.run {
144
- http = EM::P::HttpClient2.connect :host => 'www.amazon.com', :port => 443, :ssl => true
145
+ http = EM::P::HttpClient2.connect :host => 'www.apple.com', :port => 443, :ssl => true
145
146
  d = http.get "/"
146
147
  d.callback {
147
148
  EM.stop
@@ -37,14 +37,14 @@ class TestInactivityTimeout < Test::Unit::TestCase
37
37
  EM.run {
38
38
  EM.heartbeat_interval = 0.1
39
39
  EM.start_server("127.0.0.1", 12345)
40
- EM.add_timer(0.2) {
40
+ EM.add_timer(0.1) {
41
41
  $start = Time.now
42
42
  c = EM.connect("127.0.0.1", 12345, TimeoutHandler)
43
- c.comm_inactivity_timeout = 2.5
43
+ c.comm_inactivity_timeout = 0.2
44
44
  }
45
45
  }
46
46
 
47
- assert_in_delta(2.5, (Time.now - $start), 0.3)
47
+ assert_in_delta(0.2, (Time.now - $start), 0.1)
48
48
  end
49
49
 
50
50
  end
@@ -55,7 +55,15 @@ class TestLineAndTextProtocol < Test::Unit::TestCase
55
55
  EM.add_timer(0.1) { EM.stop }
56
56
  end
57
57
  end
58
-
58
+
59
+ def setup_timeout(timeout = 4)
60
+ EM.schedule {
61
+ start_time = EM.current_time
62
+ EM.add_periodic_timer(0.01) {
63
+ raise "timeout" if EM.current_time - start_time >= timeout
64
+ }
65
+ }
66
+ end
59
67
 
60
68
  def test_simple_lines
61
69
  lines_received = []
@@ -63,7 +71,7 @@ class TestLineAndTextProtocol < Test::Unit::TestCase
63
71
  EventMachine.start_server( TestHost, TestPort, SimpleLineTest ) do |conn|
64
72
  conn.instance_eval "@line_buffer = lines_received"
65
73
  end
66
- EventMachine.add_timer(4) {assert(false, "test timed out")}
74
+ setup_timeout
67
75
 
68
76
  EventMachine.connect TestHost, TestPort, StopClient do |c|
69
77
  c.send_data "aaa\nbbb\r\nccc\n"
@@ -87,7 +95,7 @@ class TestLineAndTextProtocol < Test::Unit::TestCase
87
95
  EventMachine.start_server( TestHost, TestPort, SimpleLineTest ) do |conn|
88
96
  conn.instance_eval "@error_message = lines_received"
89
97
  end
90
- EventMachine.add_timer(4) {assert(false, "test timed out")}
98
+ setup_timeout
91
99
 
92
100
  EventMachine.connect TestHost, TestPort, StopClient do |c|
93
101
  c.send_data "a" * (16*1024 + 1)
@@ -126,7 +134,7 @@ class TestLineAndTextProtocol < Test::Unit::TestCase
126
134
  EventMachine.start_server( TestHost, TestPort, LineAndTextTest ) do |conn|
127
135
  conn.instance_eval "@lines = lines_received; @text = text_received"
128
136
  end
129
- EventMachine.add_timer(4) {assert(false, "test timed out")}
137
+ setup_timeout
130
138
 
131
139
  EventMachine.connect TestHost, TestPort, StopClient do |c|
132
140
  c.set_receive_data { |data| output << data }
@@ -166,7 +174,7 @@ class TestLineAndTextProtocol < Test::Unit::TestCase
166
174
  EventMachine.start_server( TestHost, TestPort, BinaryTextTest ) do |conn|
167
175
  conn.instance_eval "@lines = lines_received; @text = text_received"
168
176
  end
169
- EventMachine.add_timer(4) {assert(false, "test timed out")}
177
+ setup_timeout
170
178
 
171
179
  EventMachine.connect TestHost, TestPort, StopClient do |c|
172
180
  c.set_receive_data { |data| output << data }
@@ -61,7 +61,7 @@ class TestNextTick < Test::Unit::TestCase
61
61
  def test_pre_run_queue
62
62
  x = false
63
63
  EM.next_tick { EM.stop; x = true }
64
- EM.run { EM.add_timer(0.2) { EM.stop } }
64
+ EM.run { EM.add_timer(0.01) { EM.stop } }
65
65
  assert x
66
66
  end
67
67
 
@@ -39,10 +39,10 @@ class TestPendingConnectTimeout < Test::Unit::TestCase
39
39
  EM.heartbeat_interval = 0.1
40
40
  $start = Time.now
41
41
  c = EM.connect("1.2.3.4", 54321, TimeoutHandler)
42
- c.pending_connect_timeout = 5
42
+ c.pending_connect_timeout = 0.2
43
43
  }
44
44
 
45
- assert_in_delta(5, (Time.now - $start), 0.3)
45
+ assert_in_delta(0.2, (Time.now - $start), 0.1)
46
46
  end
47
47
 
48
48
  end
@@ -2,47 +2,49 @@ $:.unshift "../lib"
2
2
  require 'eventmachine'
3
3
  require 'test/unit'
4
4
 
5
- class TestProcessWatch < Test::Unit::TestCase
6
- module ParentProcessWatcher
7
- def process_forked
8
- $forked = true
5
+ if EM.kqueue?
6
+ class TestProcessWatch < Test::Unit::TestCase
7
+ module ParentProcessWatcher
8
+ def process_forked
9
+ $forked = true
10
+ end
9
11
  end
10
- end
11
12
 
12
- module ChildProcessWatcher
13
- def process_exited
14
- $exited = true
15
- end
16
- def unbind
17
- $unbind = true
18
- EM.stop
13
+ module ChildProcessWatcher
14
+ def process_exited
15
+ $exited = true
16
+ end
17
+ def unbind
18
+ $unbind = true
19
+ EM.stop
20
+ end
19
21
  end
20
- end
21
22
 
22
- def setup
23
- EM.kqueue = true if EM.kqueue?
24
- end
23
+ def setup
24
+ EM.kqueue = true
25
+ end
25
26
 
26
- def teardown
27
- EM.kqueue = false if EM.kqueue?
28
- end
27
+ def teardown
28
+ EM.kqueue = false
29
+ end
29
30
 
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
31
+ def test_events
32
+ EM.run{
33
+ # watch ourselves for a fork notification
34
+ EM.watch_process(Process.pid, ParentProcessWatcher)
35
+ $fork_pid = fork{ sleep }
36
+ child = EM.watch_process($fork_pid, ChildProcessWatcher)
37
+ $pid = child.pid
37
38
 
38
- EM.add_timer(0.5){
39
- Process.kill('TERM', $fork_pid)
39
+ EM.add_timer(0.2){
40
+ Process.kill('TERM', $fork_pid)
41
+ }
40
42
  }
41
- }
42
43
 
43
- assert_equal($pid, $fork_pid)
44
- assert($forked)
45
- assert($exited)
46
- assert($unbind)
44
+ assert_equal($pid, $fork_pid)
45
+ assert($forked)
46
+ assert($exited)
47
+ assert($unbind)
48
+ end
47
49
  end
48
- end
50
+ end