eventmachine 1.0.0.beta.3 → 1.0.0.beta.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/.gitignore +5 -0
  2. data/.yardopts +5 -1
  3. data/{docs/GNU → GNU} +0 -0
  4. data/Gemfile +1 -0
  5. data/{docs/COPYING → LICENSE} +0 -0
  6. data/README.md +109 -0
  7. data/Rakefile +8 -0
  8. data/docs/DocumentationGuidesIndex.md +27 -0
  9. data/docs/GettingStarted.md +521 -0
  10. data/docs/{ChangeLog → old/ChangeLog} +0 -0
  11. data/docs/{DEFERRABLES → old/DEFERRABLES} +0 -0
  12. data/docs/{EPOLL → old/EPOLL} +0 -0
  13. data/docs/{INSTALL → old/INSTALL} +0 -0
  14. data/docs/{KEYBOARD → old/KEYBOARD} +0 -0
  15. data/docs/{LEGAL → old/LEGAL} +0 -0
  16. data/docs/{LIGHTWEIGHT_CONCURRENCY → old/LIGHTWEIGHT_CONCURRENCY} +0 -0
  17. data/docs/{PURE_RUBY → old/PURE_RUBY} +0 -0
  18. data/docs/{RELEASE_NOTES → old/RELEASE_NOTES} +0 -0
  19. data/docs/{SMTP → old/SMTP} +0 -0
  20. data/docs/{SPAWNED_PROCESSES → old/SPAWNED_PROCESSES} +0 -0
  21. data/docs/{TODO → old/TODO} +0 -0
  22. data/eventmachine.gemspec +4 -1
  23. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  24. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  25. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  26. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  27. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  28. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  29. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  30. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  31. data/examples/{ex_channel.rb → old/ex_channel.rb} +3 -3
  32. data/examples/{ex_queue.rb → old/ex_queue.rb} +0 -0
  33. data/examples/{ex_tick_loop_array.rb → old/ex_tick_loop_array.rb} +0 -0
  34. data/examples/{ex_tick_loop_counter.rb → old/ex_tick_loop_counter.rb} +0 -0
  35. data/examples/{helper.rb → old/helper.rb} +0 -0
  36. data/ext/cmain.cpp +3 -3
  37. data/ext/ed.cpp +90 -15
  38. data/ext/ed.h +5 -5
  39. data/ext/em.cpp +47 -55
  40. data/ext/em.h +12 -2
  41. data/ext/pipe.cpp +2 -2
  42. data/ext/project.h +1 -1
  43. data/ext/rubymain.cpp +48 -3
  44. data/ext/ssl.cpp +5 -0
  45. data/java/src/com/rubyeventmachine/EmReactor.java +2 -2
  46. data/lib/em/buftok.rb +35 -63
  47. data/lib/em/callback.rb +43 -11
  48. data/lib/em/channel.rb +21 -14
  49. data/lib/em/completion.rb +304 -0
  50. data/lib/em/connection.rb +339 -209
  51. data/lib/em/deferrable.rb +4 -0
  52. data/lib/em/deferrable/pool.rb +2 -0
  53. data/lib/em/file_watch.rb +37 -18
  54. data/lib/em/iterator.rb +42 -42
  55. data/lib/em/pool.rb +146 -0
  56. data/lib/em/process_watch.rb +5 -4
  57. data/lib/em/processes.rb +8 -4
  58. data/lib/em/protocols/httpclient.rb +22 -11
  59. data/lib/em/protocols/httpclient2.rb +15 -5
  60. data/lib/em/protocols/line_protocol.rb +2 -1
  61. data/lib/em/protocols/memcache.rb +17 -9
  62. data/lib/em/protocols/object_protocol.rb +2 -1
  63. data/lib/em/protocols/postgres3.rb +8 -9
  64. data/lib/em/protocols/smtpclient.rb +19 -11
  65. data/lib/em/protocols/smtpserver.rb +1 -1
  66. data/lib/em/protocols/stomp.rb +8 -6
  67. data/lib/em/protocols/tcptest.rb +3 -2
  68. data/lib/em/pure_ruby.rb +212 -208
  69. data/lib/em/queue.rb +22 -13
  70. data/lib/em/resolver.rb +70 -64
  71. data/lib/em/spawnable.rb +6 -3
  72. data/lib/em/streamer.rb +33 -45
  73. data/lib/em/threaded_resource.rb +90 -0
  74. data/lib/em/timers.rb +6 -2
  75. data/lib/em/version.rb +1 -1
  76. data/lib/eventmachine.rb +538 -602
  77. data/lib/jeventmachine.rb +22 -1
  78. data/tasks/package.rake +12 -2
  79. data/tasks/test.rake +1 -0
  80. data/tests/em_test_helper.rb +12 -3
  81. data/tests/test_completion.rb +177 -0
  82. data/tests/test_epoll.rb +2 -2
  83. data/tests/test_httpclient.rb +9 -9
  84. data/tests/test_httpclient2.rb +11 -9
  85. data/tests/test_ltp.rb +2 -10
  86. data/tests/test_pool.rb +128 -0
  87. data/tests/test_processes.rb +20 -2
  88. data/tests/test_queue.rb +8 -0
  89. data/tests/test_resolver.rb +1 -1
  90. data/tests/test_set_sock_opt.rb +37 -0
  91. data/tests/test_shutdown_hooks.rb +23 -0
  92. data/tests/test_threaded_resource.rb +53 -0
  93. data/tests/test_unbind_reason.rb +31 -0
  94. metadata +262 -192
  95. data/README +0 -81
  96. data/tasks/doc.rake +0 -30
@@ -59,14 +59,23 @@ SocketChannel.send :include, JavaFields
59
59
  module EventMachine
60
60
  # TODO: These event numbers are defined in way too many places.
61
61
  # DRY them up.
62
+ # @private
62
63
  TimerFired = 100
64
+ # @private
63
65
  ConnectionData = 101
66
+ # @private
64
67
  ConnectionUnbound = 102
68
+ # @private
65
69
  ConnectionAccepted = 103
70
+ # @private
66
71
  ConnectionCompleted = 104
72
+ # @private
67
73
  LoopbreakSignalled = 105
74
+ # @private
68
75
  ConnectionNotifyReadable = 106
76
+ # @private
69
77
  ConnectionNotifyWritable = 107
78
+ # @private
70
79
  SslHandshakeCompleted = 108
71
80
 
72
81
  # Exceptions that are defined in rubymain.cpp
@@ -118,7 +127,7 @@ module EventMachine
118
127
  @em.sendData sig, data.to_java_bytes
119
128
  end
120
129
  def self.send_datagram sig, data, length, address, port
121
- @em.sendDatagram sig, data, length, address, port
130
+ @em.sendDatagram sig, data.to_java_bytes, length, address, port
122
131
  end
123
132
  def self.connect_server server, port
124
133
  bind_connect_server nil, nil, server, port
@@ -132,6 +141,10 @@ module EventMachine
132
141
  def self.set_comm_inactivity_timeout sig, interval
133
142
  @em.setCommInactivityTimeout sig, interval
134
143
  end
144
+ def self.set_pending_connect_timeout sig, val
145
+ end
146
+ def self.set_heartbeat_interval val
147
+ end
135
148
  def self.start_tls sig
136
149
  @em.startTls sig
137
150
  end
@@ -190,6 +203,7 @@ module EventMachine
190
203
  Socket.pack_sockaddr_in(*peer)
191
204
  end
192
205
  end
206
+ # @private
193
207
  def self.attach_fd fileno, watch_mode
194
208
  # 3Aug09: We could pass in the actual SocketChannel, but then it would be modified (set as non-blocking), and
195
209
  # we would need some logic to make sure detach_fd below didn't clobber it. For now, we just always make a new
@@ -249,6 +263,13 @@ module EventMachine
249
263
  @em.getConnectionCount
250
264
  end
251
265
 
266
+ def self.set_tls_parms(sig, params)
267
+ end
268
+ def self.start_tls(sig)
269
+ end
270
+ def self.send_file_data(sig, filename)
271
+ end
272
+
252
273
  class Connection
253
274
  def associate_callback_target sig
254
275
  # No-op for the time being
@@ -1,6 +1,16 @@
1
1
  require 'rake/gempackagetask'
2
- require 'rake/extensiontask'
3
- require 'rake/javaextensiontask'
2
+ begin
3
+ require 'rake/extensiontask'
4
+ require 'rake/javaextensiontask'
5
+ rescue LoadError => e
6
+ puts <<-MSG
7
+ rake-compiler gem seems to be missing. Please install it with
8
+
9
+ gem install rake-compiler
10
+
11
+ (add sudo if necessary).
12
+ MSG
13
+ end
4
14
 
5
15
  Rake::GemPackageTask.new(GEMSPEC) do |pkg|
6
16
  end
@@ -2,6 +2,7 @@ require 'rake/testtask'
2
2
 
3
3
  Rake::TestTask.new(:test) do |t|
4
4
  t.libs << "tests"
5
+ t.libs << "lib"
5
6
  t.pattern = 'tests/**/test_*.rb'
6
7
  t.warning = true
7
8
  end
@@ -1,9 +1,9 @@
1
- require 'lib/eventmachine'
1
+ require 'eventmachine'
2
2
  require 'test/unit'
3
3
  require 'rbconfig'
4
4
  require 'socket'
5
5
 
6
- Test::Unit::TestCase.class_eval do
6
+ class Test::Unit::TestCase
7
7
  class EMTestTimeout < StandardError ; end
8
8
 
9
9
  def setup_timeout(timeout = TIMEOUT_INTERVAL)
@@ -38,7 +38,7 @@ Test::Unit::TestCase.class_eval do
38
38
  module PlatformHelper
39
39
  # http://blog.emptyway.com/2009/11/03/proper-way-to-detect-windows-platform-in-ruby/
40
40
  def windows?
41
- Config::CONFIG['host_os'] =~ /mswin|mingw/
41
+ RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
42
42
  end
43
43
 
44
44
  # http://stackoverflow.com/questions/1342535/how-can-i-tell-if-im-running-from-jruby-vs-ruby/1685970#1685970
@@ -52,4 +52,13 @@ Test::Unit::TestCase.class_eval do
52
52
 
53
53
  # Tests run significantly slower on windows. YMMV
54
54
  TIMEOUT_INTERVAL = windows? ? 1 : 0.25
55
+
56
+ def silent
57
+ backup, $VERBOSE = $VERBOSE, nil
58
+ begin
59
+ yield
60
+ ensure
61
+ $VERBOSE = backup
62
+ end
63
+ end
55
64
  end
@@ -0,0 +1,177 @@
1
+ require 'em/completion'
2
+
3
+ class TestCompletion < Test::Unit::TestCase
4
+ def completion
5
+ @completion ||= EM::Completion.new
6
+ end
7
+
8
+ def crank
9
+ # This is a slow solution, but this just executes the next tick queue
10
+ # once. It's the easiest way for now.
11
+ EM.run { EM.stop }
12
+ end
13
+
14
+ def results
15
+ @results ||= []
16
+ end
17
+
18
+ def test_state
19
+ assert_equal :unknown, completion.state
20
+ end
21
+
22
+ def test_succeed
23
+ completion.callback { |val| results << val }
24
+ completion.succeed :object
25
+ crank
26
+ assert_equal :succeeded, completion.state
27
+ assert_equal [:object], results
28
+ end
29
+
30
+ def test_fail
31
+ completion.errback { |val| results << val }
32
+ completion.fail :object
33
+ crank
34
+ assert_equal :failed, completion.state
35
+ assert_equal [:object], results
36
+ end
37
+
38
+ def test_callback
39
+ completion.callback { results << :callback }
40
+ completion.errback { results << :errback }
41
+ completion.succeed
42
+ crank
43
+ assert_equal [:callback], results
44
+ end
45
+
46
+ def test_errback
47
+ completion.callback { results << :callback }
48
+ completion.errback { results << :errback }
49
+ completion.fail
50
+ crank
51
+ assert_equal [:errback], results
52
+ end
53
+
54
+ def test_stateback
55
+ completion.stateback(:magic) { results << :stateback }
56
+ completion.change_state(:magic)
57
+ crank
58
+ assert_equal [:stateback], results
59
+ end
60
+
61
+ def test_does_not_enqueue_when_completed
62
+ completion.callback { results << :callback }
63
+ completion.succeed
64
+ completion.errback { results << :errback }
65
+ completion.fail
66
+ crank
67
+ assert_equal [:callback], results
68
+ end
69
+
70
+ def test_completed
71
+ assert_equal false, completion.completed?
72
+ completion.succeed
73
+ assert_equal true, completion.completed?
74
+ completion.fail
75
+ assert_equal true, completion.completed?
76
+ completion.change_state :magic
77
+ assert_equal false, completion.completed?
78
+ end
79
+
80
+ def test_recursive_callbacks
81
+ completion.callback do |val|
82
+ results << val
83
+ completion.succeed :two
84
+ end
85
+ completion.callback do |val|
86
+ results << val
87
+ completion.succeed :three
88
+ end
89
+ completion.callback do |val|
90
+ results << val
91
+ end
92
+ completion.succeed :one
93
+ crank
94
+ assert_equal [:one, :two, :three], results
95
+ end
96
+
97
+ def test_late_defined_callbacks
98
+ completion.callback { results << :one }
99
+ completion.succeed
100
+ crank
101
+ assert_equal [:one], results
102
+ completion.callback { results << :two }
103
+ crank
104
+ assert_equal [:one, :two], results
105
+ end
106
+
107
+ def test_cleared_completions
108
+ completion.callback { results << :callback }
109
+ completion.errback { results << :errback }
110
+
111
+ completion.succeed
112
+ crank
113
+ completion.fail
114
+ crank
115
+ completion.succeed
116
+ crank
117
+
118
+ assert_equal [:callback], results
119
+ end
120
+
121
+ def test_skip_completed_callbacks
122
+ completion.callback { results << :callback }
123
+ completion.succeed
124
+ crank
125
+
126
+ completion.errback { results << :errback }
127
+ completion.fail
128
+ crank
129
+
130
+ assert_equal [:callback], results
131
+ end
132
+
133
+ def test_completions
134
+ completion.completion { results << :completion }
135
+ completion.succeed
136
+ crank
137
+ assert_equal [:completion], results
138
+
139
+ completion.change_state(:unknown)
140
+ results.clear
141
+
142
+ completion.completion { results << :completion }
143
+ completion.fail
144
+ crank
145
+ assert_equal [:completion], results
146
+ end
147
+
148
+ def test_latent_completion
149
+ completion.completion { results << :completion }
150
+ completion.succeed
151
+ crank
152
+ completion.completion { results << :completion }
153
+ crank
154
+ assert_equal [:completion, :completion], results
155
+ end
156
+
157
+ def test_timeout
158
+ args = [1, 2, 3]
159
+ EM.run do
160
+ completion.timeout(0.0001, *args)
161
+ completion.errback { |*errargs| results << errargs }
162
+ completion.completion { EM.stop }
163
+ EM.add_timer(0.1) { flunk 'test timed out' }
164
+ end
165
+ assert_equal [[1,2,3]], results
166
+ end
167
+
168
+ def test_timeout_gets_cancelled
169
+ EM.run do
170
+ completion.timeout(0.0001, :timeout)
171
+ completion.errback { results << :errback }
172
+ completion.succeed
173
+ EM.add_timer(0.0002) { EM.stop }
174
+ end
175
+ assert_equal [], results
176
+ end
177
+ end
@@ -49,7 +49,7 @@ class TestEpoll < Test::Unit::TestCase
49
49
  # XXX this test causes all sort of weird issues on OSX (when run as part of the suite)
50
50
  def _test_descriptors
51
51
  EM.epoll
52
- s = EM.set_descriptor_table_size 60000
52
+ EM.set_descriptor_table_size 60000
53
53
  EM.run {
54
54
  EM.start_server "127.0.0.1", 9800, TestEchoServer
55
55
  $n = 0
@@ -101,7 +101,7 @@ class TestEpoll < Test::Unit::TestCase
101
101
  def _test_unix_domain
102
102
  fn = "/tmp/xxx.chain"
103
103
  EM.epoll
104
- s = EM.set_descriptor_table_size 60000
104
+ EM.set_descriptor_table_size 60000
105
105
  EM.run {
106
106
  # The pure-Ruby version won't let us open the socket if the node already exists.
107
107
  # Not sure, that actually may be correct and the compiled version is wrong.
@@ -16,7 +16,7 @@ class TestHttpClient < Test::Unit::TestCase
16
16
  def test_http_client
17
17
  ok = false
18
18
  EM.run {
19
- c = EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80
19
+ c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 }
20
20
  c.callback {
21
21
  ok = true
22
22
  EM.stop
@@ -31,7 +31,7 @@ class TestHttpClient < Test::Unit::TestCase
31
31
  def test_http_client_1
32
32
  ok = false
33
33
  EM.run {
34
- c = EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80
34
+ c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 }
35
35
  c.callback {ok = true; EM.stop}
36
36
  c.errback {EM.stop}
37
37
  }
@@ -43,7 +43,7 @@ class TestHttpClient < Test::Unit::TestCase
43
43
  def test_http_client_2
44
44
  ok = false
45
45
  EM.run {
46
- c = EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80
46
+ c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 }
47
47
  c.callback {|result|
48
48
  ok = true;
49
49
  EM.stop
@@ -75,7 +75,7 @@ class TestHttpClient < Test::Unit::TestCase
75
75
  ok = false
76
76
  EM.run {
77
77
  EM.start_server "127.0.0.1", 9701, EmptyContent
78
- c = EM::P::HttpClient.send :request, :host => "127.0.0.1", :port => 9701
78
+ c = silent { EM::P::HttpClient.send :request, :host => "127.0.0.1", :port => 9701 }
79
79
  c.callback {|result|
80
80
  ok = true
81
81
  EM.stop
@@ -134,14 +134,14 @@ class TestHttpClient < Test::Unit::TestCase
134
134
  EM.run {
135
135
  EM.start_server Localhost, Localport, PostContent
136
136
  setup_timeout(2)
137
- c = EM::P::HttpClient.request(
137
+ c = silent { EM::P::HttpClient.request(
138
138
  :host=>Localhost,
139
139
  :port=>Localport,
140
140
  :method=>:post,
141
141
  :request=>"/aaa",
142
142
  :content=>"XYZ",
143
143
  :content_type=>"text/plain"
144
- )
144
+ )}
145
145
  c.callback {|r|
146
146
  response = r
147
147
  EM.stop
@@ -158,7 +158,7 @@ class TestHttpClient < Test::Unit::TestCase
158
158
  def test_cookie
159
159
  ok = false
160
160
  EM.run {
161
- c = EM::Protocols::HttpClient.send :request, :host => "www.google.com", :port => 80, :cookie=>"aaa=bbb"
161
+ c = silent { EM::Protocols::HttpClient.send :request, :host => "www.google.com", :port => 80, :cookie=>"aaa=bbb" }
162
162
  c.callback {|result|
163
163
  ok = true;
164
164
  EM.stop
@@ -173,11 +173,11 @@ class TestHttpClient < Test::Unit::TestCase
173
173
  def test_version_1_0
174
174
  ok = false
175
175
  EM.run {
176
- c = EM::P::HttpClient.request(
176
+ c = silent { EM::P::HttpClient.request(
177
177
  :host => "www.google.com",
178
178
  :port => 80,
179
179
  :version => "1.0"
180
- )
180
+ )}
181
181
  c.callback {|result|
182
182
  ok = true;
183
183
  EM.stop
@@ -22,8 +22,10 @@ class TestHttpClient2 < Test::Unit::TestCase
22
22
  def test_connect
23
23
  EM.run {
24
24
  EM.start_server Localhost, Localport, TestServer
25
- http1 = EM::P::HttpClient2.connect Localhost, Localport
26
- http2 = EM::P::HttpClient2.connect( :host=>Localhost, :port=>Localport )
25
+ silent do
26
+ EM::P::HttpClient2.connect Localhost, Localport
27
+ EM::P::HttpClient2.connect( :host=>Localhost, :port=>Localport )
28
+ end
27
29
  EM.stop
28
30
  }
29
31
  end
@@ -33,7 +35,7 @@ class TestHttpClient2 < Test::Unit::TestCase
33
35
  EM.run {
34
36
  EM.start_server Localhost, Localport, TestServer
35
37
  assert_raises( ArgumentError ) {
36
- EM::P::HttpClient2.connect Localhost, "xxx"
38
+ silent { EM::P::HttpClient2.connect Localhost, "xxx" }
37
39
  }
38
40
  EM.stop
39
41
  }
@@ -42,7 +44,7 @@ class TestHttpClient2 < Test::Unit::TestCase
42
44
  def test_bad_server
43
45
  err = nil
44
46
  EM.run {
45
- http = EM::P::HttpClient2.connect Localhost, 9999
47
+ http = silent { EM::P::HttpClient2.connect Localhost, 9999 }
46
48
  d = http.get "/"
47
49
  d.errback { err = true; d.internal_error; EM.stop }
48
50
  }
@@ -52,7 +54,7 @@ class TestHttpClient2 < Test::Unit::TestCase
52
54
  def test_get
53
55
  content = nil
54
56
  EM.run {
55
- http = EM::P::HttpClient2.connect "google.com", 80
57
+ http = silent { EM::P::HttpClient2.connect "google.com", 80 }
56
58
  d = http.get "/"
57
59
  d.callback {
58
60
  content = d.content
@@ -68,7 +70,7 @@ class TestHttpClient2 < Test::Unit::TestCase
68
70
  def _test_get_multiple
69
71
  content = nil
70
72
  EM.run {
71
- http = EM::P::HttpClient2.connect "google.com", 80
73
+ http = silent { EM::P::HttpClient2.connect "google.com", 80 }
72
74
  d = http.get "/"
73
75
  d.callback {
74
76
  e = http.get "/"
@@ -84,7 +86,7 @@ class TestHttpClient2 < Test::Unit::TestCase
84
86
  def test_get_pipeline
85
87
  headers, headers2 = nil, nil
86
88
  EM.run {
87
- http = EM::P::HttpClient2.connect "google.com", 80
89
+ http = silent { EM::P::HttpClient2.connect "google.com", 80 }
88
90
  d = http.get("/")
89
91
  d.callback {
90
92
  headers = d.headers
@@ -104,7 +106,7 @@ class TestHttpClient2 < Test::Unit::TestCase
104
106
  def test_authheader
105
107
  EM.run {
106
108
  EM.start_server Localhost, Localport, TestServer
107
- http = EM::P::HttpClient2.connect Localhost, 18842
109
+ http = silent { EM::P::HttpClient2.connect Localhost, 18842 }
108
110
  d = http.get :url=>"/", :authorization=>"Basic xxx"
109
111
  d.callback {EM.stop}
110
112
  d.errback {EM.stop}
@@ -114,7 +116,7 @@ class TestHttpClient2 < Test::Unit::TestCase
114
116
  def test_https_get
115
117
  d = nil
116
118
  EM.run {
117
- http = EM::P::HttpClient2.connect :host => 'www.apple.com', :port => 443, :ssl => true
119
+ http = silent { EM::P::HttpClient2.connect :host => 'www.apple.com', :port => 443, :ssl => true }
118
120
  d = http.get "/"
119
121
  d.callback {
120
122
  EM.stop