eventmachine 1.2.0.dev.2-x64-mingw32

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.
Files changed (181) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +105 -0
  3. data/GNU +281 -0
  4. data/LICENSE +60 -0
  5. data/README.md +108 -0
  6. data/docs/DocumentationGuidesIndex.md +27 -0
  7. data/docs/GettingStarted.md +521 -0
  8. data/docs/old/ChangeLog +211 -0
  9. data/docs/old/DEFERRABLES +246 -0
  10. data/docs/old/EPOLL +141 -0
  11. data/docs/old/INSTALL +13 -0
  12. data/docs/old/KEYBOARD +42 -0
  13. data/docs/old/LEGAL +25 -0
  14. data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
  15. data/docs/old/PURE_RUBY +75 -0
  16. data/docs/old/RELEASE_NOTES +94 -0
  17. data/docs/old/SMTP +4 -0
  18. data/docs/old/SPAWNED_PROCESSES +148 -0
  19. data/docs/old/TODO +8 -0
  20. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  21. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  22. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  23. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  24. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  25. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  26. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  27. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  28. data/examples/old/ex_channel.rb +43 -0
  29. data/examples/old/ex_queue.rb +2 -0
  30. data/examples/old/ex_tick_loop_array.rb +15 -0
  31. data/examples/old/ex_tick_loop_counter.rb +32 -0
  32. data/examples/old/helper.rb +2 -0
  33. data/ext/binder.cpp +124 -0
  34. data/ext/binder.h +46 -0
  35. data/ext/cmain.cpp +988 -0
  36. data/ext/ed.cpp +2111 -0
  37. data/ext/ed.h +442 -0
  38. data/ext/em.cpp +2379 -0
  39. data/ext/em.h +308 -0
  40. data/ext/eventmachine.h +143 -0
  41. data/ext/extconf.rb +270 -0
  42. data/ext/fastfilereader/extconf.rb +110 -0
  43. data/ext/fastfilereader/mapper.cpp +216 -0
  44. data/ext/fastfilereader/mapper.h +59 -0
  45. data/ext/fastfilereader/rubymain.cpp +127 -0
  46. data/ext/kb.cpp +79 -0
  47. data/ext/page.cpp +107 -0
  48. data/ext/page.h +51 -0
  49. data/ext/pipe.cpp +354 -0
  50. data/ext/project.h +176 -0
  51. data/ext/rubymain.cpp +1504 -0
  52. data/ext/ssl.cpp +615 -0
  53. data/ext/ssl.h +103 -0
  54. data/java/.classpath +8 -0
  55. data/java/.project +17 -0
  56. data/java/src/com/rubyeventmachine/EmReactor.java +591 -0
  57. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  58. data/java/src/com/rubyeventmachine/EventableChannel.java +72 -0
  59. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +201 -0
  60. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +415 -0
  61. data/lib/2.0/fastfilereaderext.so +0 -0
  62. data/lib/2.0/rubyeventmachine.so +0 -0
  63. data/lib/2.1/fastfilereaderext.so +0 -0
  64. data/lib/2.1/rubyeventmachine.so +0 -0
  65. data/lib/2.2/fastfilereaderext.so +0 -0
  66. data/lib/2.2/rubyeventmachine.so +0 -0
  67. data/lib/2.3/fastfilereaderext.so +0 -0
  68. data/lib/2.3/rubyeventmachine.so +0 -0
  69. data/lib/em/buftok.rb +59 -0
  70. data/lib/em/callback.rb +58 -0
  71. data/lib/em/channel.rb +69 -0
  72. data/lib/em/completion.rb +304 -0
  73. data/lib/em/connection.rb +770 -0
  74. data/lib/em/deferrable.rb +210 -0
  75. data/lib/em/deferrable/pool.rb +2 -0
  76. data/lib/em/file_watch.rb +73 -0
  77. data/lib/em/future.rb +61 -0
  78. data/lib/em/iterator.rb +252 -0
  79. data/lib/em/messages.rb +66 -0
  80. data/lib/em/pool.rb +151 -0
  81. data/lib/em/process_watch.rb +45 -0
  82. data/lib/em/processes.rb +123 -0
  83. data/lib/em/protocols.rb +37 -0
  84. data/lib/em/protocols/header_and_content.rb +138 -0
  85. data/lib/em/protocols/httpclient.rb +299 -0
  86. data/lib/em/protocols/httpclient2.rb +600 -0
  87. data/lib/em/protocols/line_and_text.rb +125 -0
  88. data/lib/em/protocols/line_protocol.rb +29 -0
  89. data/lib/em/protocols/linetext2.rb +166 -0
  90. data/lib/em/protocols/memcache.rb +331 -0
  91. data/lib/em/protocols/object_protocol.rb +46 -0
  92. data/lib/em/protocols/postgres3.rb +246 -0
  93. data/lib/em/protocols/saslauth.rb +175 -0
  94. data/lib/em/protocols/smtpclient.rb +394 -0
  95. data/lib/em/protocols/smtpserver.rb +666 -0
  96. data/lib/em/protocols/socks4.rb +66 -0
  97. data/lib/em/protocols/stomp.rb +205 -0
  98. data/lib/em/protocols/tcptest.rb +54 -0
  99. data/lib/em/pure_ruby.rb +1022 -0
  100. data/lib/em/queue.rb +80 -0
  101. data/lib/em/resolver.rb +232 -0
  102. data/lib/em/spawnable.rb +84 -0
  103. data/lib/em/streamer.rb +118 -0
  104. data/lib/em/threaded_resource.rb +90 -0
  105. data/lib/em/tick_loop.rb +85 -0
  106. data/lib/em/timers.rb +61 -0
  107. data/lib/em/version.rb +3 -0
  108. data/lib/eventmachine.rb +1584 -0
  109. data/lib/fastfilereaderext.rb +2 -0
  110. data/lib/jeventmachine.rb +301 -0
  111. data/lib/rubyeventmachine.rb +2 -0
  112. data/rakelib/package.rake +120 -0
  113. data/rakelib/test.rake +8 -0
  114. data/tests/client.crt +31 -0
  115. data/tests/client.key +51 -0
  116. data/tests/dhparam.pem +13 -0
  117. data/tests/em_test_helper.rb +151 -0
  118. data/tests/test_attach.rb +151 -0
  119. data/tests/test_basic.rb +283 -0
  120. data/tests/test_channel.rb +75 -0
  121. data/tests/test_completion.rb +178 -0
  122. data/tests/test_connection_count.rb +54 -0
  123. data/tests/test_connection_write.rb +35 -0
  124. data/tests/test_defer.rb +35 -0
  125. data/tests/test_deferrable.rb +35 -0
  126. data/tests/test_epoll.rb +142 -0
  127. data/tests/test_error_handler.rb +38 -0
  128. data/tests/test_exc.rb +28 -0
  129. data/tests/test_file_watch.rb +66 -0
  130. data/tests/test_fork.rb +75 -0
  131. data/tests/test_futures.rb +170 -0
  132. data/tests/test_get_sock_opt.rb +37 -0
  133. data/tests/test_handler_check.rb +35 -0
  134. data/tests/test_hc.rb +155 -0
  135. data/tests/test_httpclient.rb +233 -0
  136. data/tests/test_httpclient2.rb +128 -0
  137. data/tests/test_idle_connection.rb +25 -0
  138. data/tests/test_inactivity_timeout.rb +54 -0
  139. data/tests/test_ipv4.rb +125 -0
  140. data/tests/test_ipv6.rb +131 -0
  141. data/tests/test_iterator.rb +115 -0
  142. data/tests/test_kb.rb +28 -0
  143. data/tests/test_line_protocol.rb +33 -0
  144. data/tests/test_ltp.rb +138 -0
  145. data/tests/test_ltp2.rb +308 -0
  146. data/tests/test_many_fds.rb +22 -0
  147. data/tests/test_next_tick.rb +104 -0
  148. data/tests/test_object_protocol.rb +36 -0
  149. data/tests/test_pause.rb +107 -0
  150. data/tests/test_pending_connect_timeout.rb +52 -0
  151. data/tests/test_pool.rb +196 -0
  152. data/tests/test_process_watch.rb +50 -0
  153. data/tests/test_processes.rb +128 -0
  154. data/tests/test_proxy_connection.rb +180 -0
  155. data/tests/test_pure.rb +88 -0
  156. data/tests/test_queue.rb +64 -0
  157. data/tests/test_resolver.rb +104 -0
  158. data/tests/test_running.rb +14 -0
  159. data/tests/test_sasl.rb +47 -0
  160. data/tests/test_send_file.rb +217 -0
  161. data/tests/test_servers.rb +33 -0
  162. data/tests/test_set_sock_opt.rb +39 -0
  163. data/tests/test_shutdown_hooks.rb +23 -0
  164. data/tests/test_smtpclient.rb +75 -0
  165. data/tests/test_smtpserver.rb +57 -0
  166. data/tests/test_spawn.rb +293 -0
  167. data/tests/test_ssl_args.rb +78 -0
  168. data/tests/test_ssl_dhparam.rb +83 -0
  169. data/tests/test_ssl_ecdh_curve.rb +79 -0
  170. data/tests/test_ssl_extensions.rb +49 -0
  171. data/tests/test_ssl_methods.rb +65 -0
  172. data/tests/test_ssl_protocols.rb +246 -0
  173. data/tests/test_ssl_verify.rb +126 -0
  174. data/tests/test_stomp.rb +37 -0
  175. data/tests/test_system.rb +46 -0
  176. data/tests/test_threaded_resource.rb +61 -0
  177. data/tests/test_tick_loop.rb +59 -0
  178. data/tests/test_timers.rb +123 -0
  179. data/tests/test_ud.rb +8 -0
  180. data/tests/test_unbind_reason.rb +52 -0
  181. metadata +381 -0
@@ -0,0 +1,22 @@
1
+ require 'em_test_helper'
2
+ require 'socket'
3
+
4
+ class TestManyFDs < Test::Unit::TestCase
5
+ def setup
6
+ @port = next_port
7
+ end
8
+
9
+ def test_connection_class_cache
10
+ mod = Module.new
11
+ a = nil
12
+ Process.setrlimit(Process::RLIMIT_NOFILE, 4096) rescue nil
13
+ EM.run {
14
+ EM.start_server '127.0.0.1', @port, mod
15
+ 1100.times do
16
+ a = EM.connect '127.0.0.1', @port, mod
17
+ assert_kind_of EM::Connection, a
18
+ end
19
+ EM.stop
20
+ }
21
+ end
22
+ end
@@ -0,0 +1,104 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestNextTick < Test::Unit::TestCase
4
+
5
+ def test_tick_arg
6
+ pr = proc {EM.stop}
7
+ EM.run {
8
+ EM.next_tick pr
9
+ }
10
+ assert true
11
+ end
12
+
13
+ def test_tick_block
14
+ EM.run {
15
+ EM.next_tick {EM.stop}
16
+ }
17
+ assert true
18
+ end
19
+
20
+ # This illustrates the solution to a long-standing problem.
21
+ # It's now possible to correctly nest calls to EM#run.
22
+ # See the source code commentary for EM#run for more info.
23
+ #
24
+ def test_run_run
25
+ EM.run {
26
+ EM.run {
27
+ EM.next_tick {EM.stop}
28
+ }
29
+ }
30
+ end
31
+
32
+ def test_pre_run_queue
33
+ x = false
34
+ EM.next_tick { EM.stop; x = true }
35
+ EM.run { EM.add_timer(0.01) { EM.stop } }
36
+ assert x
37
+ end
38
+
39
+ def test_cleanup_after_stop
40
+ x = true
41
+ EM.run{
42
+ EM.next_tick{
43
+ EM.stop
44
+ EM.next_tick{ x=false }
45
+ }
46
+ }
47
+ EM.run{
48
+ EM.next_tick{ EM.stop }
49
+ }
50
+ assert x
51
+ end
52
+
53
+ # We now support an additional parameter for EM#run.
54
+ # You can pass two procs to EM#run now. The first is executed as the normal
55
+ # run block. The second (if given) is scheduled for execution after the
56
+ # reactor loop completes.
57
+ # The reason for supporting this is subtle. There has always been an expectation
58
+ # that EM#run doesn't return until after the reactor loop ends. But now it's
59
+ # possible to nest calls to EM#run, which means that a nested call WILL
60
+ # RETURN. In order to write code that will run correctly either way, it's
61
+ # recommended to put any code which must execute after the reactor completes
62
+ # in the second parameter.
63
+ #
64
+ def test_run_run_2
65
+ a = proc {EM.stop}
66
+ b = proc {assert true}
67
+ EM.run a, b
68
+ end
69
+
70
+
71
+ # This illustrates that EM#run returns when it's called nested.
72
+ # This isn't a feature, rather it's something to be wary of when writing code
73
+ # that must run correctly even if EM#run is called while a reactor is already
74
+ # running.
75
+ def test_run_run_3
76
+ a = []
77
+ EM.run {
78
+ EM.run proc {EM.stop}, proc {a << 2}
79
+ a << 1
80
+ }
81
+ assert_equal( [1,2], a )
82
+ end
83
+
84
+
85
+ def test_schedule_on_reactor_thread
86
+ x = false
87
+ EM.run do
88
+ EM.schedule { x = true }
89
+ EM.stop
90
+ end
91
+ assert x
92
+ end
93
+
94
+ def test_schedule_from_thread
95
+ x = false
96
+ EM.run do
97
+ Thread.new { EM.schedule { x = true } }.join
98
+ assert !x
99
+ EM.next_tick { EM.stop }
100
+ end
101
+ assert x
102
+ end
103
+
104
+ end
@@ -0,0 +1,36 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestObjectProtocol < Test::Unit::TestCase
4
+ module Server
5
+ include EM::P::ObjectProtocol
6
+ def post_init
7
+ send_object :hello=>'world'
8
+ end
9
+ def receive_object obj
10
+ $server = obj
11
+ EM.stop
12
+ end
13
+ end
14
+
15
+ module Client
16
+ include EM::P::ObjectProtocol
17
+ def receive_object obj
18
+ $client = obj
19
+ send_object 'you_said'=>obj
20
+ end
21
+ end
22
+
23
+ def setup
24
+ @port = next_port
25
+ end
26
+
27
+ def test_send_receive
28
+ EM.run{
29
+ EM.start_server "127.0.0.1", @port, Server
30
+ EM.connect "127.0.0.1", @port, Client
31
+ }
32
+
33
+ assert($client == {:hello=>'world'})
34
+ assert($server == {'you_said'=>{:hello=>'world'}})
35
+ end
36
+ end
@@ -0,0 +1,107 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestPause < Test::Unit::TestCase
4
+ if EM.respond_to? :pause_connection
5
+ def setup
6
+ @port = next_port
7
+ end
8
+
9
+ def teardown
10
+ assert(!EM.reactor_running?)
11
+ end
12
+
13
+ def test_pause_resume
14
+ server = nil
15
+
16
+ s_rx = c_rx = 0
17
+
18
+ test_server = Module.new do
19
+ define_method :post_init do
20
+ server = self
21
+ end
22
+
23
+ define_method :receive_data do |data|
24
+ s_rx += 1
25
+
26
+ EM.add_periodic_timer(0.01) { send_data 'hi' }
27
+ send_data 'hi'
28
+
29
+ # pause server, now no outgoing data will actually
30
+ # be sent and no more incoming data will be received
31
+ pause
32
+ end
33
+ end
34
+
35
+ test_client = Module.new do
36
+ def post_init
37
+ EM.add_periodic_timer(0.01) do
38
+ send_data 'hello'
39
+ end
40
+ end
41
+
42
+ define_method :receive_data do |data|
43
+ c_rx += 1
44
+ end
45
+ end
46
+
47
+ EM.run do
48
+ EM.start_server "127.0.0.1", @port, test_server
49
+ EM.connect "127.0.0.1", @port, test_client
50
+
51
+ EM.add_timer(0.05) do
52
+ assert_equal 1, s_rx
53
+ assert_equal 0, c_rx
54
+ assert server.paused?
55
+
56
+ # resume server, queued outgoing and incoming data will be flushed
57
+ server.resume
58
+
59
+ assert !server.paused?
60
+
61
+ EM.add_timer(0.05) do
62
+ assert server.paused?
63
+ assert s_rx > 1
64
+ assert c_rx > 0
65
+ EM.stop
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ def test_pause_in_receive_data
72
+ incoming = []
73
+
74
+ test_server = Module.new do
75
+ define_method(:receive_data) do |data|
76
+ incoming << data
77
+ pause
78
+ EM.add_timer(0.5){ close_connection }
79
+ end
80
+ define_method(:unbind) do
81
+ EM.stop
82
+ end
83
+ end
84
+
85
+ buf = 'a' * 1024
86
+
87
+ EM.run do
88
+ EM.start_server "127.0.0.1", @port, test_server
89
+ cli = EM.connect "127.0.0.1", @port
90
+ 128.times do
91
+ cli.send_data buf
92
+ end
93
+ end
94
+
95
+ assert_equal 1, incoming.size
96
+ assert incoming[0].bytesize > buf.bytesize
97
+ assert incoming[0].bytesize < buf.bytesize * 128
98
+ end
99
+ else
100
+ warn "EM.pause_connection not implemented, skipping tests in #{__FILE__}"
101
+
102
+ # Because some rubies will complain if a TestCase class has no tests
103
+ def test_em_pause_connection_not_implemented
104
+ assert true
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,52 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestPendingConnectTimeout < Test::Unit::TestCase
4
+
5
+ if EM.respond_to? :get_pending_connect_timeout
6
+ def test_default
7
+ EM.run {
8
+ c = EM.connect("127.0.0.1", 54321)
9
+ assert_equal 20.0, c.pending_connect_timeout
10
+ EM.stop
11
+ }
12
+ end
13
+
14
+ def test_set_and_get
15
+ EM.run {
16
+ c = EM.connect("127.0.0.1", 54321)
17
+ c.pending_connect_timeout = 2.5
18
+ assert_equal 2.5, c.pending_connect_timeout
19
+ EM.stop
20
+ }
21
+ end
22
+
23
+ def test_for_real
24
+ start, finish = nil
25
+
26
+ timeout_handler = Module.new do
27
+ define_method :unbind do
28
+ finish = Time.now
29
+ EM.stop
30
+ end
31
+ end
32
+
33
+ EM.run {
34
+ setup_timeout
35
+ EM.heartbeat_interval = 0.1
36
+ start = Time.now
37
+ c = EM.connect("1.2.3.4", 54321, timeout_handler)
38
+ c.pending_connect_timeout = 0.2
39
+ }
40
+
41
+ assert_in_delta(0.2, (finish - start), 0.1)
42
+ end
43
+ else
44
+ warn "EM.pending_connect_timeout not implemented, skipping tests in #{__FILE__}"
45
+
46
+ # Because some rubies will complain if a TestCase class has no tests
47
+ def test_em_pending_connect_timeout_not_implemented
48
+ assert true
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,196 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestPool < Test::Unit::TestCase
4
+ def pool
5
+ @pool ||= EM::Pool.new
6
+ end
7
+
8
+ def go
9
+ EM.run { yield }
10
+ end
11
+
12
+ def stop
13
+ EM.stop
14
+ end
15
+
16
+ def deferrable
17
+ @deferrable ||= EM::DefaultDeferrable.new
18
+ end
19
+
20
+ def test_supports_more_work_than_resources
21
+ ran = false
22
+ go do
23
+ pool.perform do
24
+ ran = true
25
+ deferrable
26
+ end
27
+ stop
28
+ end
29
+ assert_equal false, ran
30
+ go do
31
+ pool.add :resource
32
+ stop
33
+ end
34
+ assert_equal true, ran
35
+ end
36
+
37
+ def test_reques_resources_on_error
38
+ pooled_res, pooled_res2 = nil
39
+ pool.add :res
40
+ go do
41
+ pool.perform do |res|
42
+ pooled_res = res
43
+ deferrable
44
+ end
45
+ stop
46
+ end
47
+ deferrable.fail
48
+ go do
49
+ pool.perform do |res|
50
+ pooled_res2 = res
51
+ deferrable
52
+ end
53
+ stop
54
+ end
55
+ assert_equal :res, pooled_res
56
+ assert_equal pooled_res, pooled_res2
57
+ end
58
+
59
+ def test_supports_custom_error_handler
60
+ eres = nil
61
+ pool.on_error do |res|
62
+ eres = res
63
+ end
64
+ performs = []
65
+ pool.add :res
66
+ go do
67
+ pool.perform do |res|
68
+ performs << res
69
+ deferrable
70
+ end
71
+ pool.perform do |res|
72
+ performs << res
73
+ deferrable
74
+ end
75
+ deferrable.fail
76
+ stop
77
+ end
78
+ assert_equal :res, eres
79
+ # manual requeues required when error handler is installed:
80
+ assert_equal 1, performs.size
81
+ assert_equal :res, performs.first
82
+ end
83
+
84
+ def test_catches_successful_deferrables
85
+ performs = []
86
+ pool.add :res
87
+ go do
88
+ pool.perform { |res| performs << res; deferrable }
89
+ pool.perform { |res| performs << res; deferrable }
90
+ stop
91
+ end
92
+ assert_equal [:res], performs
93
+ deferrable.succeed
94
+ go { stop }
95
+ assert_equal [:res, :res], performs
96
+ end
97
+
98
+ def test_prunes_locked_and_removed_resources
99
+ performs = []
100
+ pool.add :res
101
+ deferrable.succeed
102
+ go do
103
+ pool.perform { |res| performs << res; pool.remove res; deferrable }
104
+ pool.perform { |res| performs << res; pool.remove res; deferrable }
105
+ stop
106
+ end
107
+ assert_equal [:res], performs
108
+ end
109
+
110
+ # Contents is only to be used for inspection of the pool!
111
+ def test_contents
112
+ pool.add :res
113
+ assert_equal [:res], pool.contents
114
+ # Assert that modifying the contents list does not affect the pools
115
+ # contents.
116
+ pool.contents.delete(:res)
117
+ assert_equal [:res], pool.contents
118
+ end
119
+
120
+ def test_contents_when_perform_errors_and_on_error_is_not_set
121
+ pool.add :res
122
+ assert_equal [:res], pool.contents
123
+
124
+ pool.perform do |r|
125
+ d = EM::DefaultDeferrable.new
126
+ d.fail
127
+ d
128
+ end
129
+
130
+ EM.run { EM.next_tick { EM.stop } }
131
+
132
+ assert_equal [:res], pool.contents
133
+ end
134
+
135
+ def test_contents_when_perform_errors_and_on_error_is_set
136
+ pool.add :res
137
+ res = nil
138
+ pool.on_error do |r|
139
+ res = r
140
+ end
141
+ assert_equal [:res], pool.contents
142
+
143
+ pool.perform do |r|
144
+ d = EM::DefaultDeferrable.new
145
+ d.fail 'foo'
146
+ d
147
+ end
148
+
149
+ EM.run { EM.next_tick { EM.stop } }
150
+
151
+ assert_equal :res, res
152
+ assert_equal [], pool.contents
153
+ end
154
+
155
+ def test_num_waiting
156
+ pool.add :res
157
+ assert_equal 0, pool.num_waiting
158
+ pool.perform { |r| EM::DefaultDeferrable.new }
159
+ assert_equal 0, pool.num_waiting
160
+ 10.times { pool.perform { |r| EM::DefaultDeferrable.new } }
161
+ EM.run { EM.next_tick { EM.stop } }
162
+ assert_equal 10, pool.num_waiting
163
+ end
164
+
165
+ def test_exceptions_in_the_work_block_bubble_up_raise_and_fail_the_resource
166
+ pool.add :res
167
+
168
+ res = nil
169
+ pool.on_error { |r| res = r }
170
+ pool.perform { raise 'boom' }
171
+
172
+ assert_raises(RuntimeError) do
173
+ EM.run { EM.next_tick { EM.stop } }
174
+ end
175
+
176
+ assert_equal [], pool.contents
177
+ assert_equal :res, res
178
+ end
179
+
180
+ def test_removed_list_does_not_leak_on_errors
181
+ pool.add :res
182
+
183
+ pool.on_error do |r|
184
+ # This is actually the wrong thing to do, and not required, but some users
185
+ # might do it. When they do, they would find that @removed would cause a
186
+ # slow leak.
187
+ pool.remove r
188
+ end
189
+
190
+ pool.perform { d = EM::DefaultDeferrable.new; d.fail; d }
191
+
192
+ EM.run { EM.next_tick { EM.stop } }
193
+ assert_equal [], pool.instance_variable_get(:@removed)
194
+ end
195
+
196
+ end