wj_eventmachine 1.3.0.dev.1

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 (180) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +179 -0
  3. data/GNU +281 -0
  4. data/LICENSE +60 -0
  5. data/README.md +110 -0
  6. data/docs/DocumentationGuidesIndex.md +27 -0
  7. data/docs/GettingStarted.md +520 -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 +52 -0
  35. data/ext/cmain.cpp +1046 -0
  36. data/ext/ed.cpp +2238 -0
  37. data/ext/ed.h +460 -0
  38. data/ext/em.cpp +2378 -0
  39. data/ext/em.h +266 -0
  40. data/ext/eventmachine.h +152 -0
  41. data/ext/extconf.rb +285 -0
  42. data/ext/fastfilereader/extconf.rb +120 -0
  43. data/ext/fastfilereader/mapper.cpp +214 -0
  44. data/ext/fastfilereader/mapper.h +59 -0
  45. data/ext/fastfilereader/rubymain.cpp +126 -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 +174 -0
  51. data/ext/rubymain.cpp +1610 -0
  52. data/ext/ssl.cpp +627 -0
  53. data/ext/ssl.h +103 -0
  54. data/ext/wait_for_single_fd.h +36 -0
  55. data/java/.classpath +8 -0
  56. data/java/.project +17 -0
  57. data/java/src/com/rubyeventmachine/EmReactor.java +625 -0
  58. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  59. data/java/src/com/rubyeventmachine/EmReactorInterface.java +70 -0
  60. data/java/src/com/rubyeventmachine/EventableChannel.java +72 -0
  61. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +201 -0
  62. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +415 -0
  63. data/java/src/com/rubyeventmachine/NullEmReactor.java +157 -0
  64. data/java/src/com/rubyeventmachine/NullEventableChannel.java +81 -0
  65. data/lib/em/buftok.rb +59 -0
  66. data/lib/em/callback.rb +58 -0
  67. data/lib/em/channel.rb +69 -0
  68. data/lib/em/completion.rb +307 -0
  69. data/lib/em/connection.rb +776 -0
  70. data/lib/em/deferrable.rb +210 -0
  71. data/lib/em/deferrable/pool.rb +2 -0
  72. data/lib/em/file_watch.rb +73 -0
  73. data/lib/em/future.rb +61 -0
  74. data/lib/em/io_streamer.rb +68 -0
  75. data/lib/em/iterator.rb +252 -0
  76. data/lib/em/messages.rb +66 -0
  77. data/lib/em/pool.rb +151 -0
  78. data/lib/em/process_watch.rb +45 -0
  79. data/lib/em/processes.rb +123 -0
  80. data/lib/em/protocols.rb +37 -0
  81. data/lib/em/protocols/header_and_content.rb +138 -0
  82. data/lib/em/protocols/httpclient.rb +303 -0
  83. data/lib/em/protocols/httpclient2.rb +602 -0
  84. data/lib/em/protocols/line_and_text.rb +125 -0
  85. data/lib/em/protocols/line_protocol.rb +33 -0
  86. data/lib/em/protocols/linetext2.rb +179 -0
  87. data/lib/em/protocols/memcache.rb +331 -0
  88. data/lib/em/protocols/object_protocol.rb +46 -0
  89. data/lib/em/protocols/postgres3.rb +246 -0
  90. data/lib/em/protocols/saslauth.rb +175 -0
  91. data/lib/em/protocols/smtpclient.rb +394 -0
  92. data/lib/em/protocols/smtpserver.rb +666 -0
  93. data/lib/em/protocols/socks4.rb +66 -0
  94. data/lib/em/protocols/stomp.rb +205 -0
  95. data/lib/em/protocols/tcptest.rb +54 -0
  96. data/lib/em/pure_ruby.rb +1299 -0
  97. data/lib/em/queue.rb +80 -0
  98. data/lib/em/resolver.rb +232 -0
  99. data/lib/em/spawnable.rb +84 -0
  100. data/lib/em/streamer.rb +118 -0
  101. data/lib/em/threaded_resource.rb +90 -0
  102. data/lib/em/tick_loop.rb +85 -0
  103. data/lib/em/timers.rb +61 -0
  104. data/lib/em/version.rb +3 -0
  105. data/lib/eventmachine.rb +1602 -0
  106. data/lib/jeventmachine.rb +318 -0
  107. data/rakelib/package.rake +120 -0
  108. data/rakelib/test.rake +6 -0
  109. data/rakelib/test_pure.rake +11 -0
  110. data/tests/client.crt +31 -0
  111. data/tests/client.key +51 -0
  112. data/tests/dhparam.pem +13 -0
  113. data/tests/em_ssl_handlers.rb +153 -0
  114. data/tests/em_test_helper.rb +198 -0
  115. data/tests/jruby/test_jeventmachine.rb +38 -0
  116. data/tests/test_attach.rb +199 -0
  117. data/tests/test_basic.rb +321 -0
  118. data/tests/test_channel.rb +75 -0
  119. data/tests/test_completion.rb +178 -0
  120. data/tests/test_connection_count.rb +83 -0
  121. data/tests/test_connection_write.rb +35 -0
  122. data/tests/test_defer.rb +35 -0
  123. data/tests/test_deferrable.rb +35 -0
  124. data/tests/test_epoll.rb +141 -0
  125. data/tests/test_error_handler.rb +38 -0
  126. data/tests/test_exc.rb +37 -0
  127. data/tests/test_file_watch.rb +86 -0
  128. data/tests/test_fork.rb +75 -0
  129. data/tests/test_futures.rb +170 -0
  130. data/tests/test_handler_check.rb +35 -0
  131. data/tests/test_hc.rb +155 -0
  132. data/tests/test_httpclient.rb +238 -0
  133. data/tests/test_httpclient2.rb +132 -0
  134. data/tests/test_idle_connection.rb +31 -0
  135. data/tests/test_inactivity_timeout.rb +102 -0
  136. data/tests/test_io_streamer.rb +47 -0
  137. data/tests/test_ipv4.rb +96 -0
  138. data/tests/test_ipv6.rb +107 -0
  139. data/tests/test_iterator.rb +122 -0
  140. data/tests/test_kb.rb +28 -0
  141. data/tests/test_keepalive.rb +113 -0
  142. data/tests/test_line_protocol.rb +33 -0
  143. data/tests/test_ltp.rb +155 -0
  144. data/tests/test_ltp2.rb +332 -0
  145. data/tests/test_many_fds.rb +21 -0
  146. data/tests/test_next_tick.rb +104 -0
  147. data/tests/test_object_protocol.rb +36 -0
  148. data/tests/test_pause.rb +109 -0
  149. data/tests/test_pending_connect_timeout.rb +52 -0
  150. data/tests/test_pool.rb +196 -0
  151. data/tests/test_process_watch.rb +50 -0
  152. data/tests/test_processes.rb +128 -0
  153. data/tests/test_proxy_connection.rb +180 -0
  154. data/tests/test_pure.rb +156 -0
  155. data/tests/test_queue.rb +64 -0
  156. data/tests/test_resolver.rb +129 -0
  157. data/tests/test_running.rb +14 -0
  158. data/tests/test_sasl.rb +46 -0
  159. data/tests/test_send_file.rb +217 -0
  160. data/tests/test_servers.rb +32 -0
  161. data/tests/test_shutdown_hooks.rb +23 -0
  162. data/tests/test_smtpclient.rb +75 -0
  163. data/tests/test_smtpserver.rb +90 -0
  164. data/tests/test_sock_opt.rb +53 -0
  165. data/tests/test_spawn.rb +290 -0
  166. data/tests/test_ssl_args.rb +41 -0
  167. data/tests/test_ssl_dhparam.rb +57 -0
  168. data/tests/test_ssl_ecdh_curve.rb +57 -0
  169. data/tests/test_ssl_extensions.rb +24 -0
  170. data/tests/test_ssl_methods.rb +31 -0
  171. data/tests/test_ssl_protocols.rb +190 -0
  172. data/tests/test_ssl_verify.rb +52 -0
  173. data/tests/test_stomp.rb +38 -0
  174. data/tests/test_system.rb +46 -0
  175. data/tests/test_threaded_resource.rb +68 -0
  176. data/tests/test_tick_loop.rb +58 -0
  177. data/tests/test_timers.rb +150 -0
  178. data/tests/test_ud.rb +8 -0
  179. data/tests/test_unbind_reason.rb +40 -0
  180. metadata +384 -0
@@ -0,0 +1,90 @@
1
+ module EventMachine
2
+ # = EventMachine::ThreadedResource
3
+ #
4
+ # A threaded resource is a "quick and dirty" wrapper around the concept of
5
+ # wiring up synchronous code into a standard EM::Pool. This is useful to keep
6
+ # interfaces coherent and provide a simple approach at "making an interface
7
+ # async-ish".
8
+ #
9
+ # General usage is to wrap libraries that do not support EventMachine, or to
10
+ # have a specific number of dedicated high-cpu worker resources.
11
+ #
12
+ # == Basic Usage example
13
+ #
14
+ # This example requires the cassandra gem. The cassandra gem contains an
15
+ # EventMachine interface, but it's sadly Fiber based and thus only works on
16
+ # 1.9. It also requires (potentially) complex stack switching logic to reach
17
+ # completion of nested operations. By contrast this approach provides a block
18
+ # in which normal synchronous code can occur, but makes no attempt to wire the
19
+ # IO into EventMachines C++ IO implementations, instead relying on the reactor
20
+ # pattern in rb_thread_select.
21
+ #
22
+ # cassandra_dispatcher = ThreadedResource.new do
23
+ # Cassandra.new('allthethings', '127.0.0.1:9160')
24
+ # end
25
+ #
26
+ # pool = EM::Pool.new
27
+ #
28
+ # pool.add cassandra_dispatcher
29
+ #
30
+ # # If we don't care about the result:
31
+ # pool.perform do |dispatcher|
32
+ # # The following block executes inside a dedicated thread, and should not
33
+ # # access EventMachine things:
34
+ # dispatcher.dispatch do |cassandra|
35
+ # cassandra.insert(:Things, '10', 'stuff' => 'things')
36
+ # end
37
+ # end
38
+ #
39
+ # # Example where we care about the result:
40
+ # pool.perform do |dispatcher|
41
+ # # The dispatch block is executed in the resources thread.
42
+ # completion = dispatcher.dispatch do |cassandra|
43
+ # cassandra.get(:Things, '10', 'stuff')
44
+ # end
45
+ #
46
+ # # This block will be yielded on the EM thread:
47
+ # completion.callback do |result|
48
+ # EM.do_something_with(result)
49
+ # end
50
+ #
51
+ # completion
52
+ # end
53
+ class ThreadedResource
54
+
55
+ # The block should return the resource that will be yielded in a dispatch.
56
+ def initialize
57
+ @resource = yield
58
+
59
+ @running = true
60
+ @queue = ::Queue.new
61
+ @thread = Thread.new do
62
+ @queue.pop.call while @running
63
+ end
64
+ end
65
+
66
+ # Called on the EM thread, generally in a perform block to return a
67
+ # completion for the work.
68
+ def dispatch
69
+ completion = EM::Completion.new
70
+ @queue << lambda do
71
+ begin
72
+ result = yield @resource
73
+ completion.succeed result
74
+ rescue => e
75
+ completion.fail e
76
+ end
77
+ end
78
+ completion
79
+ end
80
+
81
+ # Kill the internal thread. should only be used to cleanup - generally
82
+ # only required for tests.
83
+ def shutdown
84
+ @running = false
85
+ @queue << lambda {}
86
+ @thread.join
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,85 @@
1
+ module EventMachine
2
+ # Creates and immediately starts an EventMachine::TickLoop
3
+ def self.tick_loop(*a, &b)
4
+ TickLoop.new(*a, &b).start
5
+ end
6
+
7
+ # A TickLoop is useful when one needs to distribute amounts of work
8
+ # throughout ticks in order to maintain response times. It is also useful for
9
+ # simple repeated checks and metrics.
10
+ # @example
11
+ # # Here we run through an array one item per tick until it is empty,
12
+ # # printing each element.
13
+ # # When the array is empty, we return :stop from the callback, and the
14
+ # # loop will terminate.
15
+ # # When the loop terminates, the on_stop callbacks will be called.
16
+ # EM.run do
17
+ # array = (1..100).to_a
18
+ #
19
+ # tickloop = EM.tick_loop do
20
+ # if array.empty?
21
+ # :stop
22
+ # else
23
+ # puts array.shift
24
+ # end
25
+ # end
26
+ #
27
+ # tickloop.on_stop { EM.stop }
28
+ # end
29
+ #
30
+ class TickLoop
31
+
32
+ # Arguments: A callback (EM::Callback) to call each tick. If the call
33
+ # returns +:stop+ then the loop will be stopped. Any other value is
34
+ # ignored.
35
+ def initialize(*a, &b)
36
+ @work = EM::Callback(*a, &b)
37
+ @stops = []
38
+ @stopped = true
39
+ end
40
+
41
+ # Arguments: A callback (EM::Callback) to call once on the next stop (or
42
+ # immediately if already stopped).
43
+ def on_stop(*a, &b)
44
+ if @stopped
45
+ EM::Callback(*a, &b).call
46
+ else
47
+ @stops << EM::Callback(*a, &b)
48
+ end
49
+ end
50
+
51
+ # Stop the tick loop immediately, and call it's on_stop callbacks.
52
+ def stop
53
+ @stopped = true
54
+ until @stops.empty?
55
+ @stops.shift.call
56
+ end
57
+ end
58
+
59
+ # Query if the loop is stopped.
60
+ def stopped?
61
+ @stopped
62
+ end
63
+
64
+ # Start the tick loop, will raise argument error if the loop is already
65
+ # running.
66
+ def start
67
+ raise ArgumentError, "double start" unless @stopped
68
+ @stopped = false
69
+ schedule
70
+ end
71
+
72
+ private
73
+ def schedule
74
+ EM.next_tick do
75
+ next if @stopped
76
+ if @work.call == :stop
77
+ stop
78
+ else
79
+ schedule
80
+ end
81
+ end
82
+ self
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,61 @@
1
+ module EventMachine
2
+ # Creates a one-time timer
3
+ #
4
+ # timer = EventMachine::Timer.new(5) do
5
+ # # this will never fire because we cancel it
6
+ # end
7
+ # timer.cancel
8
+ #
9
+ class Timer
10
+ # Create a new timer that fires after a given number of seconds
11
+ def initialize interval, callback=nil, &block
12
+ @signature = EventMachine::add_timer(interval, callback || block)
13
+ end
14
+
15
+ # Cancel the timer
16
+ def cancel
17
+ EventMachine.send :cancel_timer, @signature
18
+ end
19
+ end
20
+
21
+ # Creates a periodic timer
22
+ #
23
+ # @example
24
+ # n = 0
25
+ # timer = EventMachine::PeriodicTimer.new(5) do
26
+ # puts "the time is #{Time.now}"
27
+ # timer.cancel if (n+=1) > 5
28
+ # end
29
+ #
30
+ class PeriodicTimer
31
+ # Create a new periodic timer that executes every interval seconds
32
+ def initialize interval, callback=nil, &block
33
+ @interval = interval
34
+ @code = callback || block
35
+ @cancelled = false
36
+ @work = method(:fire)
37
+ schedule
38
+ end
39
+
40
+ # Cancel the periodic timer
41
+ def cancel
42
+ @cancelled = true
43
+ end
44
+
45
+ # Fire the timer every interval seconds
46
+ attr_accessor :interval
47
+
48
+ # @private
49
+ def schedule
50
+ EventMachine::add_timer @interval, @work
51
+ end
52
+
53
+ # @private
54
+ def fire
55
+ unless @cancelled
56
+ @code.call
57
+ schedule
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module EventMachine
2
+ VERSION = "1.3.0.dev.1"
3
+ end
@@ -0,0 +1,1602 @@
1
+ if defined?(EventMachine.library_type) and EventMachine.library_type == :pure_ruby
2
+ # assume 'em/pure_ruby' was loaded already
3
+ elsif RUBY_PLATFORM =~ /java/
4
+ require 'java'
5
+ require 'jeventmachine'
6
+ else
7
+ begin
8
+ require 'rubyeventmachine'
9
+ rescue LoadError
10
+ warn "Unable to load the EventMachine C extension; To use the pure-ruby reactor, require 'em/pure_ruby'"
11
+ raise
12
+ end
13
+ end
14
+
15
+ require 'em/version'
16
+ require 'em/pool'
17
+ require 'em/deferrable'
18
+ require 'em/future'
19
+ require 'em/streamer'
20
+ require 'em/spawnable'
21
+ require 'em/processes'
22
+ require 'em/iterator'
23
+ require 'em/buftok'
24
+ require 'em/timers'
25
+ require 'em/protocols'
26
+ require 'em/connection'
27
+ require 'em/callback'
28
+ require 'em/queue'
29
+ require 'em/channel'
30
+ require 'em/file_watch'
31
+ require 'em/process_watch'
32
+ require 'em/tick_loop'
33
+ require 'em/resolver'
34
+ require 'em/completion'
35
+ require 'em/threaded_resource'
36
+
37
+ require 'shellwords'
38
+ require 'thread'
39
+ require 'resolv'
40
+
41
+ ##
42
+ # Top-level EventMachine namespace. If you are looking for EventMachine examples, see {file:docs/GettingStarted.md EventMachine tutorial}.
43
+ #
44
+ # ## Key methods ##
45
+ # ### Starting and stopping the event loop ###
46
+ #
47
+ # * {EventMachine.run}
48
+ # * {EventMachine.stop_event_loop}
49
+ #
50
+ # ### Implementing clients ###
51
+ #
52
+ # * {EventMachine.connect}
53
+ #
54
+ # ### Implementing servers ###
55
+ #
56
+ # * {EventMachine.start_server}
57
+ #
58
+ # ### Working with timers ###
59
+ #
60
+ # * {EventMachine.add_timer}
61
+ # * {EventMachine.add_periodic_timer}
62
+ # * {EventMachine.cancel_timer}
63
+ #
64
+ # ### Working with blocking tasks ###
65
+ #
66
+ # * {EventMachine.defer}
67
+ # * {EventMachine.next_tick}
68
+ #
69
+ # ### Efficient proxying ###
70
+ #
71
+ # * {EventMachine.enable_proxy}
72
+ # * {EventMachine.disable_proxy}
73
+ module EventMachine
74
+ class << self
75
+ # Exposed to allow joining on the thread, when run in a multithreaded
76
+ # environment. Performing other actions on the thread has undefined
77
+ # semantics (read: a dangerous endevor).
78
+ #
79
+ # @return [Thread]
80
+ attr_reader :reactor_thread
81
+ end
82
+ @next_tick_mutex = Mutex.new
83
+ @reactor_running = false
84
+ @next_tick_queue = []
85
+ @tails = []
86
+ @threadpool = @threadqueue = @resultqueue = nil
87
+ @all_threads_spawned = false
88
+
89
+ # System errnos
90
+ # @private
91
+ ERRNOS = Errno::constants.grep(/^E/).inject(Hash.new(:unknown)) { |hash, name|
92
+ errno = Errno.__send__(:const_get, name)
93
+ hash[errno::Errno] = errno
94
+ hash
95
+ }
96
+
97
+ # Initializes and runs an event loop. This method only returns if code inside the block passed to this method
98
+ # calls {EventMachine.stop_event_loop}. The block is executed after initializing its internal event loop but *before* running the loop,
99
+ # therefore this block is the right place to call any code that needs event loop to run, for example, {EventMachine.start_server},
100
+ # {EventMachine.connect} or similar methods of libraries that use EventMachine under the hood
101
+ # (like `EventMachine::HttpRequest.new` or `AMQP.start`).
102
+ #
103
+ # Programs that are run for long periods of time (e.g. servers) usually start event loop by calling {EventMachine.run}, and let it
104
+ # run "forever". It's also possible to use {EventMachine.run} to make a single client-connection to a remote server,
105
+ # process the data flow from that single connection, and then call {EventMachine.stop_event_loop} to stop, in other words,
106
+ # to run event loop for a short period of time (necessary to complete some operation) and then shut it down.
107
+ #
108
+ # Once event loop is running, it is perfectly possible to start multiple servers and clients simultaneously: content-aware
109
+ # proxies like [Proxymachine](https://github.com/mojombo/proxymachine) do just that.
110
+ #
111
+ # ## Using EventMachine with Ruby on Rails and other Web application frameworks
112
+ #
113
+ # Standalone applications often run event loop on the main thread, thus blocking for their entire lifespan. In case of Web applications,
114
+ # if you are running an EventMachine-based app server such as [Thin](http://code.macournoyer.com/thin/) or [Goliath](https://github.com/postrank-labs/goliath/),
115
+ # they start event loop for you. Servers like Unicorn, Apache Passenger or Mongrel occupy main Ruby thread to serve HTTP(S) requests. This means
116
+ # that calling {EventMachine.run} on the same thread is not an option (it will result in Web server never binding to the socket).
117
+ # In that case, start event loop in a separate thread as demonstrated below.
118
+ #
119
+ #
120
+ # @example Starting EventMachine event loop in the current thread to run the "Hello, world"-like Echo server example
121
+ #
122
+ # #!/usr/bin/env ruby
123
+ #
124
+ # require 'rubygems' # or use Bundler.setup
125
+ # require 'eventmachine'
126
+ #
127
+ # class EchoServer < EM::Connection
128
+ # def receive_data(data)
129
+ # send_data(data)
130
+ # end
131
+ # end
132
+ #
133
+ # EventMachine.run do
134
+ # EventMachine.start_server("0.0.0.0", 10000, EchoServer)
135
+ # end
136
+ #
137
+ #
138
+ # @example Starting EventMachine event loop in a separate thread
139
+ #
140
+ # # doesn't block current thread, can be used with Ruby on Rails, Sinatra, Merb, Rack
141
+ # # and any other application server that occupies main Ruby thread.
142
+ # Thread.new { EventMachine.run }
143
+ #
144
+ #
145
+ # @note This method blocks calling thread. If you need to start EventMachine event loop from a Web app
146
+ # running on a non event-driven server (Unicorn, Apache Passenger, Mongrel), do it in a separate thread like demonstrated
147
+ # in one of the examples.
148
+ # @see file:docs/GettingStarted.md Getting started with EventMachine
149
+ # @see EventMachine.stop_event_loop
150
+ def self.run blk=nil, tail=nil, &block
151
+ # Obsoleted the use_threads mechanism.
152
+ # 25Nov06: Added the begin/ensure block. We need to be sure that release_machine
153
+ # gets called even if an exception gets thrown within any of the user code
154
+ # that the event loop runs. The best way to see this is to run a unit
155
+ # test with two functions, each of which calls {EventMachine.run} and each of
156
+ # which throws something inside of #run. Without the ensure, the second test
157
+ # will start without release_machine being called and will immediately throw
158
+
159
+ #
160
+ if @reactor_running and @reactor_pid != Process.pid
161
+ # Reactor was started in a different parent, meaning we have forked.
162
+ # Clean up reactor state so a new reactor boots up in this child.
163
+ stop_event_loop
164
+ release_machine
165
+ cleanup_machine
166
+ @reactor_running = false
167
+ end
168
+
169
+ tail and @tails.unshift(tail)
170
+
171
+ if reactor_running?
172
+ (b = blk || block) and b.call # next_tick(b)
173
+ else
174
+ @conns = {}
175
+ @acceptors = {}
176
+ @timers = {}
177
+ @wrapped_exception = nil
178
+ @next_tick_queue ||= []
179
+ @tails ||= []
180
+ begin
181
+ initialize_event_machine
182
+ @reactor_pid = Process.pid
183
+ @reactor_thread = Thread.current
184
+ @reactor_running = true
185
+
186
+ (b = blk || block) and add_timer(0, b)
187
+ if @next_tick_queue && !@next_tick_queue.empty?
188
+ add_timer(0) { signal_loopbreak }
189
+ end
190
+
191
+ # Rubinius needs to come back into "Ruby space" for GC to work,
192
+ # so we'll crank the machine here.
193
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
194
+ while run_machine_once; end
195
+ else
196
+ run_machine
197
+ end
198
+
199
+ ensure
200
+ until @tails.empty?
201
+ @tails.pop.call
202
+ end
203
+
204
+ release_machine
205
+ cleanup_machine
206
+ @reactor_running = false
207
+ @reactor_thread = nil
208
+ end
209
+
210
+ raise @wrapped_exception if @wrapped_exception
211
+ end
212
+ end
213
+
214
+ # Sugars a common use case. Will pass the given block to #run, but will terminate
215
+ # the reactor loop and exit the function as soon as the code in the block completes.
216
+ # (Normally, {EventMachine.run} keeps running indefinitely, even after the block supplied to it
217
+ # finishes running, until user code calls {EventMachine.stop})
218
+ #
219
+ def self.run_block &block
220
+ pr = proc {
221
+ block.call
222
+ EventMachine::stop
223
+ }
224
+ run(&pr)
225
+ end
226
+
227
+ # @return [Boolean] true if the calling thread is the same thread as the reactor.
228
+ def self.reactor_thread?
229
+ Thread.current == @reactor_thread
230
+ end
231
+
232
+ # Runs the given callback on the reactor thread, or immediately if called
233
+ # from the reactor thread. Accepts the same arguments as {EventMachine::Callback}
234
+ def self.schedule(*a, &b)
235
+ cb = Callback(*a, &b)
236
+ if reactor_running? && reactor_thread?
237
+ cb.call
238
+ else
239
+ next_tick { cb.call }
240
+ end
241
+ end
242
+
243
+ # Forks a new process, properly stops the reactor and then calls {EventMachine.run} inside of it again, passing your block.
244
+ def self.fork_reactor &block
245
+ # This implementation is subject to change, especially if we clean up the relationship
246
+ # of EM#run to @reactor_running.
247
+ # Original patch by Aman Gupta.
248
+ #
249
+ Kernel.fork do
250
+ if reactor_running?
251
+ stop_event_loop
252
+ release_machine
253
+ cleanup_machine
254
+ @reactor_running = false
255
+ @reactor_thread = nil
256
+ end
257
+ run block
258
+ end
259
+ end
260
+
261
+ # Clean up Ruby space following a release_machine
262
+ def self.cleanup_machine
263
+ if @threadpool && !@threadpool.empty?
264
+ # Tell the threads to stop
265
+ @threadpool.each { |t| t.exit }
266
+ # Join the threads or bump the stragglers one more time
267
+ @threadpool.each { |t| t.join 0.01 || t.exit }
268
+ end
269
+ @threadpool = nil
270
+ @threadqueue = nil
271
+ @resultqueue = nil
272
+ @all_threads_spawned = false
273
+ @next_tick_queue = []
274
+ end
275
+
276
+ # Adds a block to call as the reactor is shutting down.
277
+ #
278
+ # These callbacks are called in the _reverse_ order to which they are added.
279
+ #
280
+ # @example Scheduling operations to be run when EventMachine event loop is stopped
281
+ #
282
+ # EventMachine.run do
283
+ # EventMachine.add_shutdown_hook { puts "b" }
284
+ # EventMachine.add_shutdown_hook { puts "a" }
285
+ # EventMachine.stop
286
+ # end
287
+ #
288
+ # # Outputs:
289
+ # # a
290
+ # # b
291
+ #
292
+ def self.add_shutdown_hook &block
293
+ @tails << block
294
+ end
295
+
296
+ # Adds a one-shot timer to the event loop.
297
+ # Call it with one or two parameters. The first parameters is a delay-time
298
+ # expressed in *seconds* (not milliseconds). The second parameter, if
299
+ # present, must be an object that responds to :call. If 2nd parameter is not given, then you
300
+ # can also simply pass a block to the method call.
301
+ #
302
+ # This method may be called from the block passed to {EventMachine.run}
303
+ # or from any callback method. It schedules execution of the proc or block
304
+ # passed to it, after the passage of an interval of time equal to
305
+ # *at least* the number of seconds specified in the first parameter to
306
+ # the call.
307
+ #
308
+ # {EventMachine.add_timer} is a non-blocking method. Callbacks can and will
309
+ # be called during the interval of time that the timer is in effect.
310
+ # There is no built-in limit to the number of timers that can be outstanding at
311
+ # any given time.
312
+ #
313
+ # @example Setting a one-shot timer with EventMachine
314
+ #
315
+ # EventMachine.run {
316
+ # puts "Starting the run now: #{Time.now}"
317
+ # EventMachine.add_timer 5, proc { puts "Executing timer event: #{Time.now}" }
318
+ # EventMachine.add_timer(10) { puts "Executing timer event: #{Time.now}" }
319
+ # }
320
+ #
321
+ # @param [Integer] delay Delay in seconds
322
+ # @see EventMachine::Timer
323
+ # @see EventMachine.add_periodic_timer
324
+ def self.add_timer *args, &block
325
+ interval = args.shift
326
+ code = args.shift || block
327
+ if code
328
+ # check too many timers!
329
+ s = add_oneshot_timer((interval.to_f * 1000).to_i)
330
+ @timers[s] = code
331
+ s
332
+ end
333
+ end
334
+
335
+ # Adds a periodic timer to the event loop.
336
+ # It takes the same parameters as the one-shot timer method, {EventMachine.add_timer}.
337
+ # This method schedules execution of the given block repeatedly, at intervals
338
+ # of time *at least* as great as the number of seconds given in the first
339
+ # parameter to the call.
340
+ #
341
+ # @example Write a dollar-sign to stderr every five seconds, without blocking
342
+ #
343
+ # EventMachine.run {
344
+ # EventMachine.add_periodic_timer(5) { $stderr.write "$" }
345
+ # }
346
+ #
347
+ # @param [Integer] delay Delay in seconds
348
+ #
349
+ # @see EventMachine::PeriodicTimer
350
+ # @see EventMachine.add_timer
351
+ #
352
+ def self.add_periodic_timer *args, &block
353
+ interval = args.shift
354
+ code = args.shift || block
355
+
356
+ EventMachine::PeriodicTimer.new(interval, code)
357
+ end
358
+
359
+
360
+ # Cancel a timer (can be a callback or an {EventMachine::Timer} instance).
361
+ #
362
+ # @param [#cancel, #call] timer_or_sig A timer to cancel
363
+ # @see EventMachine::Timer#cancel
364
+ def self.cancel_timer timer_or_sig
365
+ if timer_or_sig.respond_to? :cancel
366
+ timer_or_sig.cancel
367
+ else
368
+ @timers[timer_or_sig] = false if @timers.has_key?(timer_or_sig)
369
+ end
370
+ end
371
+
372
+
373
+ # Causes the processing loop to stop executing, which will cause all open connections and accepting servers
374
+ # to be run down and closed. Connection termination callbacks added using {EventMachine.add_shutdown_hook}
375
+ # will be called as part of running this method.
376
+ #
377
+ # When all of this processing is complete, the call to {EventMachine.run} which started the processing loop
378
+ # will return and program flow will resume from the statement following {EventMachine.run} call.
379
+ #
380
+ # @example Stopping a running EventMachine event loop
381
+ #
382
+ # require 'rubygems'
383
+ # require 'eventmachine'
384
+ #
385
+ # module Redmond
386
+ # def post_init
387
+ # puts "We're sending a dumb HTTP request to the remote peer."
388
+ # send_data "GET / HTTP/1.1\r\nHost: www.microsoft.com\r\n\r\n"
389
+ # end
390
+ #
391
+ # def receive_data data
392
+ # puts "We received #{data.length} bytes from the remote peer."
393
+ # puts "We're going to stop the event loop now."
394
+ # EventMachine::stop_event_loop
395
+ # end
396
+ #
397
+ # def unbind
398
+ # puts "A connection has terminated."
399
+ # end
400
+ # end
401
+ #
402
+ # puts "We're starting the event loop now."
403
+ # EventMachine.run {
404
+ # EventMachine.connect "www.microsoft.com", 80, Redmond
405
+ # }
406
+ # puts "The event loop has stopped."
407
+ #
408
+ # # This program will produce approximately the following output:
409
+ # #
410
+ # # We're starting the event loop now.
411
+ # # We're sending a dumb HTTP request to the remote peer.
412
+ # # We received 1440 bytes from the remote peer.
413
+ # # We're going to stop the event loop now.
414
+ # # A connection has terminated.
415
+ # # The event loop has stopped.
416
+ #
417
+ #
418
+ def self.stop_event_loop
419
+ EventMachine::stop
420
+ end
421
+
422
+ # Initiates a TCP server (socket acceptor) on the specified IP address and port.
423
+ #
424
+ # The IP address must be valid on the machine where the program
425
+ # runs, and the process must be privileged enough to listen
426
+ # on the specified port (on Unix-like systems, superuser privileges
427
+ # are usually required to listen on any port lower than 1024).
428
+ # Only one listener may be running on any given address/port
429
+ # combination. start_server will fail if the given address and port
430
+ # are already listening on the machine, either because of a prior call
431
+ # to {.start_server} or some unrelated process running on the machine.
432
+ # If {.start_server} succeeds, the new network listener becomes active
433
+ # immediately and starts accepting connections from remote peers,
434
+ # and these connections generate callback events that are processed
435
+ # by the code specified in the handler parameter to {.start_server}.
436
+ #
437
+ # The optional handler which is passed to this method is the key
438
+ # to EventMachine's ability to handle particular network protocols.
439
+ # The handler parameter passed to start_server must be a Ruby Module
440
+ # that you must define. When the network server that is started by
441
+ # start_server accepts a new connection, it instantiates a new
442
+ # object of an anonymous class that is inherited from {EventMachine::Connection},
443
+ # *into which your handler module have been included*. Arguments passed into start_server
444
+ # after the class name are passed into the constructor during the instantiation.
445
+ #
446
+ # Your handler module may override any of the methods in {EventMachine::Connection},
447
+ # such as {EventMachine::Connection#receive_data}, in order to implement the specific behavior
448
+ # of the network protocol.
449
+ #
450
+ # Callbacks invoked in response to network events *always* take place
451
+ # within the execution context of the object derived from {EventMachine::Connection}
452
+ # extended by your handler module. There is one object per connection, and
453
+ # all of the callbacks invoked for a particular connection take the form
454
+ # of instance methods called against the corresponding {EventMachine::Connection}
455
+ # object. Therefore, you are free to define whatever instance variables you
456
+ # wish, in order to contain the per-connection state required by the network protocol you are
457
+ # implementing.
458
+ #
459
+ # {EventMachine.start_server} is usually called inside the block passed to {EventMachine.run},
460
+ # but it can be called from any EventMachine callback. {EventMachine.start_server} will fail
461
+ # unless the EventMachine event loop is currently running (which is why
462
+ # it's often called in the block suppled to {EventMachine.run}).
463
+ #
464
+ # You may call start_server any number of times to start up network
465
+ # listeners on different address/port combinations. The servers will
466
+ # all run simultaneously. More interestingly, each individual call to start_server
467
+ # can specify a different handler module and thus implement a different
468
+ # network protocol from all the others.
469
+ #
470
+ # @example
471
+ #
472
+ # require 'rubygems'
473
+ # require 'eventmachine'
474
+ #
475
+ # # Here is an example of a server that counts lines of input from the remote
476
+ # # peer and sends back the total number of lines received, after each line.
477
+ # # Try the example with more than one client connection opened via telnet,
478
+ # # and you will see that the line count increments independently on each
479
+ # # of the client connections. Also very important to note, is that the
480
+ # # handler for the receive_data function, which our handler redefines, may
481
+ # # not assume that the data it receives observes any kind of message boundaries.
482
+ # # Also, to use this example, be sure to change the server and port parameters
483
+ # # to the start_server call to values appropriate for your environment.
484
+ # module LineCounter
485
+ # MaxLinesPerConnection = 10
486
+ #
487
+ # def post_init
488
+ # puts "Received a new connection"
489
+ # @data_received = ""
490
+ # @line_count = 0
491
+ # end
492
+ #
493
+ # def receive_data data
494
+ # @data_received << data
495
+ # while @data_received.slice!( /^[^\n]*[\n]/m )
496
+ # @line_count += 1
497
+ # send_data "received #{@line_count} lines so far\r\n"
498
+ # @line_count == MaxLinesPerConnection and close_connection_after_writing
499
+ # end
500
+ # end
501
+ # end
502
+ #
503
+ # EventMachine.run {
504
+ # host, port = "192.168.0.100", 8090
505
+ # EventMachine.start_server host, port, LineCounter
506
+ # puts "Now accepting connections on address #{host}, port #{port}..."
507
+ # EventMachine.add_periodic_timer(10) { $stderr.write "*" }
508
+ # }
509
+ #
510
+ # @param [String] server Host to bind to.
511
+ # @param [Integer] port Port to bind to.
512
+ # @param [Module, Class] handler A module or class that implements connection callbacks
513
+ #
514
+ # @note Don't forget that in order to bind to ports < 1024 on Linux, *BSD and Mac OS X your process must have superuser privileges.
515
+ #
516
+ # @see file:docs/GettingStarted.md EventMachine tutorial
517
+ # @see EventMachine.stop_server
518
+ def self.start_server server, port=nil, handler=nil, *args, &block
519
+ begin
520
+ port = Integer(port)
521
+ rescue ArgumentError, TypeError
522
+ # there was no port, so server must be a unix domain socket
523
+ # the port argument is actually the handler, and the handler is one of the args
524
+ args.unshift handler if handler
525
+ handler = port
526
+ port = nil
527
+ end if port
528
+
529
+ klass = klass_from_handler(Connection, handler, *args)
530
+
531
+ s = if port
532
+ start_tcp_server server, port
533
+ else
534
+ start_unix_server server
535
+ end
536
+ @acceptors[s] = [klass,args,block]
537
+ s
538
+ end
539
+
540
+ # Attach to an existing socket's file descriptor. The socket may have been
541
+ # started with {EventMachine.start_server}.
542
+ def self.attach_server sock, handler=nil, *args, &block
543
+ klass = klass_from_handler(Connection, handler, *args)
544
+ sd = sock.respond_to?(:fileno) ? sock.fileno : sock
545
+ s = attach_sd(sd)
546
+ @acceptors[s] = [klass,args,block,sock]
547
+ s
548
+ end
549
+
550
+ # Stop a TCP server socket that was started with {EventMachine.start_server}.
551
+ # @see EventMachine.start_server
552
+ def self.stop_server signature
553
+ EventMachine::stop_tcp_server signature
554
+ end
555
+
556
+ # Start a Unix-domain server.
557
+ #
558
+ # Note that this is an alias for {EventMachine.start_server}, which can be used to start both
559
+ # TCP and Unix-domain servers.
560
+ #
561
+ # @see EventMachine.start_server
562
+ def self.start_unix_domain_server filename, *args, &block
563
+ start_server filename, *args, &block
564
+ end
565
+
566
+ # Initiates a TCP connection to a remote server and sets up event handling for the connection.
567
+ # {EventMachine.connect} requires event loop to be running (see {EventMachine.run}).
568
+ #
569
+ # {EventMachine.connect} takes the IP address (or hostname) and
570
+ # port of the remote server you want to connect to.
571
+ # It also takes an optional handler (a module or a subclass of {EventMachine::Connection}) which you must define, that
572
+ # contains the callbacks that will be invoked by the event loop on behalf of the connection.
573
+ #
574
+ # Learn more about connection lifecycle callbacks in the {file:docs/GettingStarted.md EventMachine tutorial} and
575
+ # {file:docs/ConnectionLifecycleCallbacks.md Connection lifecycle guide}.
576
+ #
577
+ #
578
+ # @example
579
+ #
580
+ # # Here's a program which connects to a web server, sends a naive
581
+ # # request, parses the HTTP header of the response, and then
582
+ # # (antisocially) ends the event loop, which automatically drops the connection
583
+ # # (and incidentally calls the connection's unbind method).
584
+ # module DumbHttpClient
585
+ # def post_init
586
+ # send_data "GET / HTTP/1.1\r\nHost: _\r\n\r\n"
587
+ # @data = ""
588
+ # @parsed = false
589
+ # end
590
+ #
591
+ # def receive_data data
592
+ # @data << data
593
+ # if !@parsed and @data =~ /[\n][\r]*[\n]/m
594
+ # @parsed = true
595
+ # puts "RECEIVED HTTP HEADER:"
596
+ # $`.each {|line| puts ">>> #{line}" }
597
+ #
598
+ # puts "Now we'll terminate the loop, which will also close the connection"
599
+ # EventMachine::stop_event_loop
600
+ # end
601
+ # end
602
+ #
603
+ # def unbind
604
+ # puts "A connection has terminated"
605
+ # end
606
+ # end
607
+ #
608
+ # EventMachine.run {
609
+ # EventMachine.connect "www.bayshorenetworks.com", 80, DumbHttpClient
610
+ # }
611
+ # puts "The event loop has ended"
612
+ #
613
+ #
614
+ # @example Defining protocol handler as a class
615
+ #
616
+ # class MyProtocolHandler < EventMachine::Connection
617
+ # def initialize *args
618
+ # super
619
+ # # whatever else you want to do here
620
+ # end
621
+ #
622
+ # # ...
623
+ # end
624
+ #
625
+ #
626
+ # @param [String] server Host to connect to
627
+ # @param [Integer] port Port to connect to
628
+ # @param [Module, Class] handler A module or class that implements connection lifecycle callbacks
629
+ #
630
+ # @see EventMachine.start_server
631
+ # @see file:docs/GettingStarted.md EventMachine tutorial
632
+ def self.connect server, port=nil, handler=nil, *args, &blk
633
+ # EventMachine::connect initiates a TCP connection to a remote
634
+ # server and sets up event-handling for the connection.
635
+ # It internally creates an object that should not be handled
636
+ # by the caller. HOWEVER, it's often convenient to get the
637
+ # object to set up interfacing to other objects in the system.
638
+ # We return the newly-created anonymous-class object to the caller.
639
+ # It's expected that a considerable amount of code will depend
640
+ # on this behavior, so don't change it.
641
+ #
642
+ # Ok, added support for a user-defined block, 13Apr06.
643
+ # This leads us to an interesting choice because of the
644
+ # presence of the post_init call, which happens in the
645
+ # initialize method of the new object. We call the user's
646
+ # block and pass the new object to it. This is a great
647
+ # way to do protocol-specific initiation. It happens
648
+ # AFTER post_init has been called on the object, which I
649
+ # certainly hope is the right choice.
650
+ # Don't change this lightly, because accepted connections
651
+ # are different from connected ones and we don't want
652
+ # to have them behave differently with respect to post_init
653
+ # if at all possible.
654
+
655
+ bind_connect nil, nil, server, port, handler, *args, &blk
656
+ end
657
+
658
+ # This method is like {EventMachine.connect}, but allows for a local address/port
659
+ # to bind the connection to.
660
+ #
661
+ # @see EventMachine.connect
662
+ def self.bind_connect bind_addr, bind_port, server, port=nil, handler=nil, *args
663
+ begin
664
+ port = Integer(port)
665
+ rescue ArgumentError, TypeError
666
+ # there was no port, so server must be a unix domain socket
667
+ # the port argument is actually the handler, and the handler is one of the args
668
+ args.unshift handler if handler
669
+ handler = port
670
+ port = nil
671
+ end if port
672
+
673
+ klass = klass_from_handler(Connection, handler, *args)
674
+
675
+ s = if port
676
+ if bind_addr
677
+ bind_connect_server bind_addr, bind_port.to_i, server, port
678
+ else
679
+ connect_server server, port
680
+ end
681
+ else
682
+ connect_unix_server server
683
+ end
684
+
685
+ c = klass.new s, *args
686
+ @conns[s] = c
687
+ block_given? and yield c
688
+ c
689
+ end
690
+
691
+ # {EventMachine.watch} registers a given file descriptor or IO object with the eventloop. The
692
+ # file descriptor will not be modified (it will remain blocking or non-blocking).
693
+ #
694
+ # The eventloop can be used to process readable and writable events on the file descriptor, using
695
+ # {EventMachine::Connection#notify_readable=} and {EventMachine::Connection#notify_writable=}
696
+ #
697
+ # {EventMachine::Connection#notify_readable?} and {EventMachine::Connection#notify_writable?} can be used
698
+ # to check what events are enabled on the connection.
699
+ #
700
+ # To detach the file descriptor, use {EventMachine::Connection#detach}
701
+ #
702
+ # @example
703
+ #
704
+ # module SimpleHttpClient
705
+ # def notify_readable
706
+ # header = @io.readline
707
+ #
708
+ # if header == "\r\n"
709
+ # # detach returns the file descriptor number (fd == @io.fileno)
710
+ # fd = detach
711
+ # end
712
+ # rescue EOFError
713
+ # detach
714
+ # end
715
+ #
716
+ # def unbind
717
+ # EM.next_tick do
718
+ # # socket is detached from the eventloop, but still open
719
+ # data = @io.read
720
+ # end
721
+ # end
722
+ # end
723
+ #
724
+ # EventMachine.run {
725
+ # sock = TCPSocket.new('site.com', 80)
726
+ # sock.write("GET / HTTP/1.0\r\n\r\n")
727
+ # conn = EventMachine.watch(sock, SimpleHttpClient)
728
+ # conn.notify_readable = true
729
+ # }
730
+ #
731
+ # @author Riham Aldakkak (eSpace Technologies)
732
+ def EventMachine::watch io, handler=nil, *args, &blk
733
+ attach_io io, true, handler, *args, &blk
734
+ end
735
+
736
+ # Attaches an IO object or file descriptor to the eventloop as a regular connection.
737
+ # The file descriptor will be set as non-blocking, and EventMachine will process
738
+ # receive_data and send_data events on it as it would for any other connection.
739
+ #
740
+ # To watch a fd instead, use {EventMachine.watch}, which will not alter the state of the socket
741
+ # and fire notify_readable and notify_writable events instead.
742
+ def EventMachine::attach io, handler=nil, *args, &blk
743
+ attach_io io, false, handler, *args, &blk
744
+ end
745
+
746
+ # @private
747
+ def EventMachine::attach_io io, watch_mode, handler=nil, *args
748
+ klass = klass_from_handler(Connection, handler, *args)
749
+
750
+ if !watch_mode and klass.public_instance_methods.any?{|m| [:notify_readable, :notify_writable].include? m.to_sym }
751
+ raise ArgumentError, "notify_readable/writable with EM.attach is not supported. Use EM.watch(io){ |c| c.notify_readable = true }"
752
+ end
753
+
754
+ if io.respond_to?(:fileno)
755
+ # getDescriptorByFileno deprecated in JRuby 1.7.x, removed in JRuby 9000
756
+ if defined?(JRuby) && JRuby.runtime.respond_to?(:getDescriptorByFileno)
757
+ fd = JRuby.runtime.getDescriptorByFileno(io.fileno).getChannel
758
+ else
759
+ fd = io.fileno
760
+ end
761
+ else
762
+ fd = io
763
+ end
764
+
765
+ s = attach_fd fd, watch_mode
766
+ c = klass.new s, *args
767
+
768
+ c.instance_variable_set(:@io, io)
769
+ c.instance_variable_set(:@watch_mode, watch_mode)
770
+ c.instance_variable_set(:@fd, fd)
771
+
772
+ @conns[s] = c
773
+ block_given? and yield c
774
+ c
775
+ end
776
+
777
+
778
+ # Connect to a given host/port and re-use the provided {EventMachine::Connection} instance.
779
+ # Consider also {EventMachine::Connection#reconnect}.
780
+ #
781
+ # @see EventMachine::Connection#reconnect
782
+ def self.reconnect server, port, handler
783
+ # Observe, the test for already-connected FAILS if we call a reconnect inside post_init,
784
+ # because we haven't set up the connection in @conns by that point.
785
+ # RESIST THE TEMPTATION to "fix" this problem by redefining the behavior of post_init.
786
+ #
787
+ # Changed 22Nov06: if called on an already-connected handler, just return the
788
+ # handler and do nothing more. Originally this condition raised an exception.
789
+ # We may want to change it yet again and call the block, if any.
790
+
791
+ raise "invalid handler" unless handler.respond_to?(:connection_completed)
792
+ #raise "still connected" if @conns.has_key?(handler.signature)
793
+ return handler if @conns.has_key?(handler.signature)
794
+
795
+ s = if port
796
+ connect_server server, port
797
+ else
798
+ connect_unix_server server
799
+ end
800
+ handler.signature = s
801
+ @conns[s] = handler
802
+ block_given? and yield handler
803
+ handler
804
+ end
805
+
806
+
807
+ # Make a connection to a Unix-domain socket. This method is simply an alias for {.connect},
808
+ # which can connect to both TCP and Unix-domain sockets. Make sure that your process has sufficient
809
+ # permissions to open the socket it is given.
810
+ #
811
+ # @param [String] socketname Unix domain socket (local fully-qualified path) you want to connect to.
812
+ #
813
+ # @note UNIX sockets, as the name suggests, are not available on Microsoft Windows.
814
+ def self.connect_unix_domain socketname, *args, &blk
815
+ connect socketname, *args, &blk
816
+ end
817
+
818
+
819
+ # Used for UDP-based protocols. Its usage is similar to that of {EventMachine.start_server}.
820
+ #
821
+ # This method will create a new UDP (datagram) socket and
822
+ # bind it to the address and port that you specify.
823
+ # The normal callbacks (see {EventMachine.start_server}) will
824
+ # be called as events of interest occur on the newly-created
825
+ # socket, but there are some differences in how they behave.
826
+ #
827
+ # {Connection#receive_data} will be called when a datagram packet
828
+ # is received on the socket, but unlike TCP sockets, the message
829
+ # boundaries of the received data will be respected. In other words,
830
+ # if the remote peer sent you a datagram of a particular size,
831
+ # you may rely on {Connection#receive_data} to give you the
832
+ # exact data in the packet, with the original data length.
833
+ # Also observe that Connection#receive_data may be called with a
834
+ # *zero-length* data payload, since empty datagrams are permitted in UDP.
835
+ #
836
+ # {Connection#send_data} is available with UDP packets as with TCP,
837
+ # but there is an important difference. Because UDP communications
838
+ # are *connectionless*, there is no implicit recipient for the packets you
839
+ # send. Ordinarily you must specify the recipient for each packet you send.
840
+ # However, EventMachine provides for the typical pattern of receiving a UDP datagram
841
+ # from a remote peer, performing some operation, and then sending
842
+ # one or more packets in response to the same remote peer.
843
+ # To support this model easily, just use {Connection#send_data}
844
+ # in the code that you supply for {Connection#receive_data}.
845
+ #
846
+ # EventMachine will provide an implicit return address for any messages sent to
847
+ # {Connection#send_data} within the context of a {Connection#receive_data} callback,
848
+ # and your response will automatically go to the correct remote peer.
849
+ #
850
+ # Observe that the port number that you supply to {EventMachine.open_datagram_socket}
851
+ # may be zero. In this case, EventMachine will create a UDP socket
852
+ # that is bound to an [ephemeral port](http://en.wikipedia.org/wiki/Ephemeral_port).
853
+ # This is not appropriate for servers that must publish a well-known
854
+ # port to which remote peers may send datagrams. But it can be useful
855
+ # for clients that send datagrams to other servers.
856
+ # If you do this, you will receive any responses from the remote
857
+ # servers through the normal {Connection#receive_data} callback.
858
+ # Observe that you will probably have issues with firewalls blocking
859
+ # the ephemeral port numbers, so this technique is most appropriate for LANs.
860
+ #
861
+ # If you wish to send datagrams to arbitrary remote peers (not
862
+ # necessarily ones that have sent data to which you are responding),
863
+ # then see {Connection#send_datagram}.
864
+ #
865
+ # DO NOT call send_data from a datagram socket outside of a {Connection#receive_data} method. Use {Connection#send_datagram}.
866
+ # If you do use {Connection#send_data} outside of a {Connection#receive_data} method, you'll get a confusing error
867
+ # because there is no "peer," as #send_data requires (inside of {EventMachine::Connection#receive_data},
868
+ # {EventMachine::Connection#send_data} "fakes" the peer as described above).
869
+ #
870
+ # @param [String] address IP address
871
+ # @param [String] port Port
872
+ # @param [Class, Module] handler A class or a module that implements connection lifecycle callbacks.
873
+ def self.open_datagram_socket address, port, handler=nil, *args
874
+ # Replaced the implementation on 01Oct06. Thanks to Tobias Gustafsson for pointing
875
+ # out that this originally did not take a class but only a module.
876
+
877
+
878
+ klass = klass_from_handler(Connection, handler, *args)
879
+ s = open_udp_socket address, port.to_i
880
+ c = klass.new s, *args
881
+ @conns[s] = c
882
+ block_given? and yield c
883
+ c
884
+ end
885
+
886
+
887
+ # For advanced users. This function sets the default timer granularity, which by default is
888
+ # slightly smaller than 100 milliseconds. Call this function to set a higher or lower granularity.
889
+ # The function affects the behavior of {EventMachine.add_timer} and {EventMachine.add_periodic_timer}.
890
+ # Most applications will not need to call this function.
891
+ #
892
+ # Avoid setting the quantum to very low values because that may reduce performance under some extreme conditions.
893
+ # We recommend that you not use values lower than 10.
894
+ #
895
+ # This method only can be used if event loop is running.
896
+ #
897
+ # @param [Integer] mills New timer granularity, in milliseconds
898
+ #
899
+ # @see EventMachine.add_timer
900
+ # @see EventMachine.add_periodic_timer
901
+ # @see EventMachine::Timer
902
+ # @see EventMachine.run
903
+ def self.set_quantum mills
904
+ set_timer_quantum mills.to_i
905
+ end
906
+
907
+ # Sets the maximum number of timers and periodic timers that may be outstanding at any
908
+ # given time. You only need to call {.set_max_timers} if you need more than the default
909
+ # number of timers, which on most platforms is 1000.
910
+ #
911
+ # @note This method has to be used *before* event loop is started.
912
+ #
913
+ # @param [Integer] ct Maximum number of timers that may be outstanding at any given time
914
+ #
915
+ # @see EventMachine.add_timer
916
+ # @see EventMachine.add_periodic_timer
917
+ # @see EventMachine::Timer
918
+ def self.set_max_timers ct
919
+ set_max_timer_count ct
920
+ end
921
+
922
+ # Gets the current maximum number of allowed timers
923
+ #
924
+ # @return [Integer] Maximum number of timers that may be outstanding at any given time
925
+ def self.get_max_timers
926
+ get_max_timer_count
927
+ end
928
+
929
+ # Returns the total number of connections (file descriptors) currently held by the reactor.
930
+ # Note that a tick must pass after the 'initiation' of a connection for this number to increment.
931
+ # It's usually accurate, but don't rely on the exact precision of this number unless you really know EM internals.
932
+ #
933
+ # @example
934
+ #
935
+ # EventMachine.run {
936
+ # EventMachine.connect("rubyeventmachine.com", 80)
937
+ # # count will be 0 in this case, because connection is not
938
+ # # established yet
939
+ # count = EventMachine.connection_count
940
+ # }
941
+ #
942
+ #
943
+ # @example
944
+ #
945
+ # EventMachine.run {
946
+ # EventMachine.connect("rubyeventmachine.com", 80)
947
+ #
948
+ # EventMachine.next_tick {
949
+ # # In this example, count will be 1 since the connection has been established in
950
+ # # the next loop of the reactor.
951
+ # count = EventMachine.connection_count
952
+ # }
953
+ # }
954
+ #
955
+ # @return [Integer] Number of connections currently held by the reactor.
956
+ def self.connection_count
957
+ self.get_connection_count
958
+ end
959
+
960
+ # The is the responder for the loopback-signalled event.
961
+ # It can be fired either by code running on a separate thread ({EventMachine.defer}) or on
962
+ # the main thread ({EventMachine.next_tick}).
963
+ # It will often happen that a next_tick handler will reschedule itself. We
964
+ # consume a copy of the tick queue so that tick events scheduled by tick events
965
+ # have to wait for the next pass through the reactor core.
966
+ #
967
+ # @private
968
+ def self.run_deferred_callbacks
969
+ until (@resultqueue ||= []).empty?
970
+ result,cback = @resultqueue.pop
971
+ cback.call result if cback
972
+ end
973
+
974
+ # Capture the size at the start of this tick...
975
+ size = @next_tick_mutex.synchronize { @next_tick_queue.size }
976
+ size.times do |i|
977
+ callback = @next_tick_mutex.synchronize { @next_tick_queue.shift }
978
+ begin
979
+ callback.call
980
+ rescue
981
+ exception_raised = true
982
+ raise
983
+ ensure
984
+ # This is a little nasty. The problem is, if an exception occurs during
985
+ # the callback, then we need to send a signal to the reactor to actually
986
+ # do some work during the next_tick. The only mechanism we have from the
987
+ # ruby side is next_tick itself, although ideally, we'd just drop a byte
988
+ # on the loopback descriptor.
989
+ next_tick {} if exception_raised
990
+ end
991
+ end
992
+ end
993
+
994
+
995
+ # EventMachine.defer is used for integrating blocking operations into EventMachine's control flow.
996
+ # The action of {.defer} is to take the block specified in the first parameter (the "operation")
997
+ # and schedule it for asynchronous execution on an internal thread pool maintained by EventMachine.
998
+ # When the operation completes, it will pass the result computed by the block (if any) back to the
999
+ # EventMachine reactor. Then, EventMachine calls the block specified in the second parameter to
1000
+ # {.defer} (the "callback"), as part of its normal event handling loop. The result computed by the
1001
+ # operation block is passed as a parameter to the callback. You may omit the callback parameter if
1002
+ # you don't need to execute any code after the operation completes. If the operation raises an
1003
+ # unhandled exception, the exception will be passed to the third parameter to {.defer} (the
1004
+ # "errback"), as part of its normal event handling loop. If no errback is provided, the exception
1005
+ # will be allowed to blow through to the main thread immediately.
1006
+ #
1007
+ # ## Caveats ##
1008
+ #
1009
+ # Note carefully that the code in your deferred operation will be executed on a separate
1010
+ # thread from the main EventMachine processing and all other Ruby threads that may exist in
1011
+ # your program. Also, multiple deferred operations may be running at once! Therefore, you
1012
+ # are responsible for ensuring that your operation code is threadsafe.
1013
+ #
1014
+ # Don't write a deferred operation that will block forever. If so, the current implementation will
1015
+ # not detect the problem, and the thread will never be returned to the pool. EventMachine limits
1016
+ # the number of threads in its pool, so if you do this enough times, your subsequent deferred
1017
+ # operations won't get a chance to run.
1018
+ #
1019
+ # The threads within the EventMachine's thread pool have abort_on_exception set to true. As a result,
1020
+ # if an unhandled exception is raised by the deferred operation and an errback is not provided, it
1021
+ # will blow through to the main thread immediately. If the main thread is within an indiscriminate
1022
+ # rescue block at that time, the exception could be handled improperly by the main thread.
1023
+ #
1024
+ # @example
1025
+ #
1026
+ # operation = proc {
1027
+ # # perform a long-running operation here, such as a database query.
1028
+ # "result" # as usual, the last expression evaluated in the block will be the return value.
1029
+ # }
1030
+ # callback = proc {|result|
1031
+ # # do something with result here, such as send it back to a network client.
1032
+ # }
1033
+ # errback = proc {|error|
1034
+ # # do something with error here, such as re-raising or logging.
1035
+ # }
1036
+ #
1037
+ # EventMachine.defer(operation, callback, errback)
1038
+ #
1039
+ # @param [#call] op An operation you want to offload to EventMachine thread pool
1040
+ # @param [#call] callback A callback that will be run on the event loop thread after `operation` finishes.
1041
+ # @param [#call] errback An errback that will be run on the event loop thread after `operation` raises an exception.
1042
+ #
1043
+ # @see EventMachine.threadpool_size
1044
+ def self.defer op = nil, callback = nil, errback = nil, &blk
1045
+ # OBSERVE that #next_tick hacks into this mechanism, so don't make any changes here
1046
+ # without syncing there.
1047
+ #
1048
+ # Running with $VERBOSE set to true gives a warning unless all ivars are defined when
1049
+ # they appear in rvalues. But we DON'T ever want to initialize @threadqueue unless we
1050
+ # need it, because the Ruby threads are so heavyweight. We end up with this bizarre
1051
+ # way of initializing @threadqueue because EventMachine is a Module, not a Class, and
1052
+ # has no constructor.
1053
+
1054
+ unless @threadpool
1055
+ @threadpool = []
1056
+ @threadqueue = ::Queue.new
1057
+ @resultqueue = ::Queue.new
1058
+ spawn_threadpool
1059
+ end
1060
+
1061
+ @threadqueue << [op||blk,callback,errback]
1062
+ end
1063
+
1064
+
1065
+ # @private
1066
+ def self.spawn_threadpool
1067
+ until @threadpool.size == @threadpool_size.to_i
1068
+ thread = Thread.new do
1069
+ Thread.current.abort_on_exception = true
1070
+ while true
1071
+ begin
1072
+ op, cback, eback = *@threadqueue.pop
1073
+ rescue ThreadError
1074
+ $stderr.puts $!.message
1075
+ break # Ruby 2.0 may fail at Queue.pop
1076
+ end
1077
+ begin
1078
+ result = op.call
1079
+ @resultqueue << [result, cback]
1080
+ rescue Exception => error
1081
+ raise error unless eback
1082
+ @resultqueue << [error, eback]
1083
+ end
1084
+ signal_loopbreak
1085
+ end
1086
+ end
1087
+ @threadpool << thread
1088
+ end
1089
+ @all_threads_spawned = true
1090
+ end
1091
+
1092
+ ##
1093
+ # Returns +true+ if all deferred actions are done executing and their
1094
+ # callbacks have been fired.
1095
+ #
1096
+ def self.defers_finished?
1097
+ return false if @threadpool and !@all_threads_spawned
1098
+ return false if @threadqueue and not @threadqueue.empty?
1099
+ return false if @resultqueue and not @resultqueue.empty?
1100
+ return false if @threadpool and @threadqueue.num_waiting != @threadpool.size
1101
+ return true
1102
+ end
1103
+
1104
+ class << self
1105
+ # @private
1106
+ attr_reader :threadpool
1107
+
1108
+ # Size of the EventMachine.defer threadpool (defaults to 20)
1109
+ # @return [Number]
1110
+ attr_accessor :threadpool_size
1111
+ EventMachine.threadpool_size = 20
1112
+ end
1113
+
1114
+ # Schedules a proc for execution immediately after the next "turn" through the reactor
1115
+ # core. An advanced technique, this can be useful for improving memory management and/or
1116
+ # application responsiveness, especially when scheduling large amounts of data for
1117
+ # writing to a network connection.
1118
+ #
1119
+ # This method takes either a single argument (which must be a callable object) or a block.
1120
+ #
1121
+ # @param [#call] pr A callable object to run
1122
+ def self.next_tick pr=nil, &block
1123
+ # This works by adding to the @resultqueue that's used for #defer.
1124
+ # The general idea is that next_tick is used when we want to give the reactor a chance
1125
+ # to let other operations run, either to balance the load out more evenly, or to let
1126
+ # outbound network buffers drain, or both. So we probably do NOT want to block, and
1127
+ # we probably do NOT want to be spinning any threads. A program that uses next_tick
1128
+ # but not #defer shouldn't suffer the penalty of having Ruby threads running. They're
1129
+ # extremely expensive even if they're just sleeping.
1130
+
1131
+ raise ArgumentError, "no proc or block given" unless ((pr && pr.respond_to?(:call)) or block)
1132
+ @next_tick_mutex.synchronize do
1133
+ @next_tick_queue << ( pr || block )
1134
+ end
1135
+ signal_loopbreak if reactor_running?
1136
+ end
1137
+
1138
+ # A wrapper over the setuid system call. Particularly useful when opening a network
1139
+ # server on a privileged port because you can use this call to drop privileges
1140
+ # after opening the port. Also very useful after a call to {.set_descriptor_table_size},
1141
+ # which generally requires that you start your process with root privileges.
1142
+ #
1143
+ # This method is intended for use in enforcing security requirements, consequently
1144
+ # it will throw a fatal error and end your program if it fails.
1145
+ #
1146
+ # @param [String] username The effective name of the user whose privilege-level your process should attain.
1147
+ #
1148
+ # @note This method has no effective implementation on Windows or in the pure-Ruby
1149
+ # implementation of EventMachine
1150
+ def self.set_effective_user username
1151
+ EventMachine::setuid_string username
1152
+ end
1153
+
1154
+
1155
+ # Sets the maximum number of file or socket descriptors that your process may open.
1156
+ # If you call this method with no arguments, it will simply return
1157
+ # the current size of the descriptor table without attempting to change it.
1158
+ #
1159
+ # The new limit on open descriptors **only** applies to sockets and other descriptors
1160
+ # that belong to EventMachine. It has **no effect** on the number of descriptors
1161
+ # you can create in ordinary Ruby code.
1162
+ #
1163
+ # Not available on all platforms. Increasing the number of descriptors beyond its
1164
+ # default limit usually requires superuser privileges. (See {.set_effective_user}
1165
+ # for a way to drop superuser privileges while your program is running.)
1166
+ #
1167
+ # @param [Integer] n_descriptors The maximum number of file or socket descriptors that your process may open
1168
+ # @return [Integer] The new descriptor table size.
1169
+ def self.set_descriptor_table_size n_descriptors=nil
1170
+ EventMachine::set_rlimit_nofile n_descriptors
1171
+ end
1172
+
1173
+
1174
+
1175
+ # Runs an external process.
1176
+ #
1177
+ # @example
1178
+ #
1179
+ # module RubyCounter
1180
+ # def post_init
1181
+ # # count up to 5
1182
+ # send_data "5\n"
1183
+ # end
1184
+ # def receive_data data
1185
+ # puts "ruby sent me: #{data}"
1186
+ # end
1187
+ # def unbind
1188
+ # puts "ruby died with exit status: #{get_status.exitstatus}"
1189
+ # end
1190
+ # end
1191
+ #
1192
+ # EventMachine.run {
1193
+ # EventMachine.popen("ruby -e' $stdout.sync = true; gets.to_i.times{ |i| puts i+1; sleep 1 } '", RubyCounter)
1194
+ # }
1195
+ #
1196
+ # @note This method is not supported on Microsoft Windows
1197
+ # @see EventMachine::DeferrableChildProcess
1198
+ # @see EventMachine.system
1199
+ def self.popen cmd, handler=nil, *args
1200
+ # At this moment, it's only available on Unix.
1201
+ # Perhaps misnamed since the underlying function uses socketpair and is full-duplex.
1202
+
1203
+ klass = klass_from_handler(Connection, handler, *args)
1204
+ w = case cmd
1205
+ when Array
1206
+ cmd
1207
+ when String
1208
+ Shellwords::shellwords( cmd )
1209
+ end
1210
+ w.unshift( w.first ) if w.first
1211
+ s = invoke_popen( w )
1212
+ c = klass.new s, *args
1213
+ @conns[s] = c
1214
+ yield(c) if block_given?
1215
+ c
1216
+ end
1217
+
1218
+
1219
+ # Tells you whether the EventMachine reactor loop is currently running.
1220
+ #
1221
+ # Useful when writing libraries that want to run event-driven code, but may
1222
+ # be running in programs that are already event-driven. In such cases, if {EventMachine.reactor_running?}
1223
+ # returns false, your code can invoke {EventMachine.run} and run your application code inside
1224
+ # the block passed to that method. If this method returns true, just
1225
+ # execute your event-aware code.
1226
+ #
1227
+ # @return [Boolean] true if the EventMachine reactor loop is currently running
1228
+ def self.reactor_running?
1229
+ @reactor_running && Process.pid == @reactor_pid
1230
+ end
1231
+
1232
+
1233
+ # (Experimental)
1234
+ #
1235
+ # @private
1236
+ def self.open_keyboard handler=nil, *args
1237
+ klass = klass_from_handler(Connection, handler, *args)
1238
+
1239
+ s = read_keyboard
1240
+ c = klass.new s, *args
1241
+ @conns[s] = c
1242
+ block_given? and yield c
1243
+ c
1244
+ end
1245
+
1246
+ # EventMachine's file monitoring API. Currently supported are the following events
1247
+ # on individual files, using inotify on Linux systems, and kqueue for *BSD and Mac OS X:
1248
+ #
1249
+ # * File modified (written to)
1250
+ # * File moved/renamed
1251
+ # * File deleted
1252
+ #
1253
+ # EventMachine::watch_file takes a filename and a handler Module containing your custom callback methods.
1254
+ # This will setup the low level monitoring on the specified file, and create a new EventMachine::FileWatch
1255
+ # object with your Module mixed in. FileWatch is a subclass of {EventMachine::Connection}, so callbacks on this object
1256
+ # work in the familiar way. The callbacks that will be fired by EventMachine are:
1257
+ #
1258
+ # * file_modified
1259
+ # * file_moved
1260
+ # * file_deleted
1261
+ #
1262
+ # You can access the filename being monitored from within this object using {FileWatch#path}.
1263
+ #
1264
+ # When a file is deleted, {FileWatch#stop_watching} will be called after your file_deleted callback,
1265
+ # to clean up the underlying monitoring and remove EventMachine's reference to the now-useless {FileWatch} instance.
1266
+ # This will in turn call unbind, if you wish to use it.
1267
+ #
1268
+ # The corresponding system-level Errno will be raised when attempting to monitor non-existent files,
1269
+ # files with wrong permissions, or if an error occurs dealing with inotify/kqueue.
1270
+ #
1271
+ # @example
1272
+ #
1273
+ # # Before running this example, make sure we have a file to monitor:
1274
+ # # $ echo "bar" > /tmp/foo
1275
+ #
1276
+ # module Handler
1277
+ # def file_modified
1278
+ # puts "#{path} modified"
1279
+ # end
1280
+ #
1281
+ # def file_moved
1282
+ # puts "#{path} moved"
1283
+ # end
1284
+ #
1285
+ # def file_deleted
1286
+ # puts "#{path} deleted"
1287
+ # end
1288
+ #
1289
+ # def unbind
1290
+ # puts "#{path} monitoring ceased"
1291
+ # end
1292
+ # end
1293
+ #
1294
+ # # for efficient file watching, use kqueue on Mac OS X
1295
+ # EventMachine.kqueue = true if EventMachine.kqueue?
1296
+ #
1297
+ # EventMachine.run {
1298
+ # EventMachine.watch_file("/tmp/foo", Handler)
1299
+ # }
1300
+ #
1301
+ # # $ echo "baz" >> /tmp/foo => "/tmp/foo modified"
1302
+ # # $ mv /tmp/foo /tmp/oof => "/tmp/foo moved"
1303
+ # # $ rm /tmp/oof => "/tmp/foo deleted"
1304
+ #
1305
+ # @note The ability to pick up on the new filename after a rename is not yet supported.
1306
+ # Calling #path will always return the filename you originally used.
1307
+ #
1308
+ # @param [String] filename Local path to the file to watch.
1309
+ # @param [Class, Module] handler A class or module that implements event handlers associated with the file.
1310
+ def self.watch_file(filename, handler=nil, *args)
1311
+ klass = klass_from_handler(FileWatch, handler, *args)
1312
+
1313
+ s = EM::watch_filename(filename)
1314
+ c = klass.new s, *args
1315
+ # we have to set the path like this because of how Connection.new works
1316
+ c.instance_variable_set("@path", filename)
1317
+ @conns[s] = c
1318
+ block_given? and yield c
1319
+ c
1320
+ end
1321
+
1322
+ # EventMachine's process monitoring API. On Mac OS X and *BSD this method is implemented using kqueue.
1323
+ #
1324
+ # @example
1325
+ #
1326
+ # module ProcessWatcher
1327
+ # def process_exited
1328
+ # put 'the forked child died!'
1329
+ # end
1330
+ # end
1331
+ #
1332
+ # pid = fork{ sleep }
1333
+ #
1334
+ # EventMachine.run {
1335
+ # EventMachine.watch_process(pid, ProcessWatcher)
1336
+ # EventMachine.add_timer(1){ Process.kill('TERM', pid) }
1337
+ # }
1338
+ #
1339
+ # @param [Integer] pid PID of the process to watch.
1340
+ # @param [Class, Module] handler A class or module that implements event handlers associated with the file.
1341
+ def self.watch_process(pid, handler=nil, *args)
1342
+ pid = pid.to_i
1343
+
1344
+ klass = klass_from_handler(ProcessWatch, handler, *args)
1345
+
1346
+ s = EM::watch_pid(pid)
1347
+ c = klass.new s, *args
1348
+ # we have to set the path like this because of how Connection.new works
1349
+ c.instance_variable_set("@pid", pid)
1350
+ @conns[s] = c
1351
+ block_given? and yield c
1352
+ c
1353
+ end
1354
+
1355
+ # Catch-all for errors raised during event loop callbacks.
1356
+ #
1357
+ # @example
1358
+ #
1359
+ # EventMachine.error_handler{ |e|
1360
+ # puts "Error raised during event loop: #{e.message}"
1361
+ # }
1362
+ #
1363
+ # @param [#call] cb Global catch-all errback
1364
+ def self.error_handler cb = nil, &blk
1365
+ if cb or blk
1366
+ @error_handler = cb || blk
1367
+ elsif instance_variable_defined? :@error_handler
1368
+ remove_instance_variable :@error_handler
1369
+ end
1370
+ end
1371
+
1372
+ # This method allows for direct writing of incoming data back out to another descriptor, at the C++ level in the reactor.
1373
+ # This is very efficient and especially useful for proxies where high performance is required. Propogating data from a server response
1374
+ # all the way up to Ruby, and then back down to the reactor to be sent back to the client, is often unnecessary and
1375
+ # incurs a significant performance decrease.
1376
+ #
1377
+ # The two arguments are instance of {EventMachine::Connection} subclasses, 'from' and 'to'. 'from' is the connection whose inbound data you want
1378
+ # relayed back out. 'to' is the connection to write it to.
1379
+ #
1380
+ # Once you call this method, the 'from' connection will no longer get receive_data callbacks from the reactor,
1381
+ # except in the case that 'to' connection has already closed when attempting to write to it. You can see
1382
+ # in the example, that proxy_target_unbound will be called when this occurs. After that, further incoming
1383
+ # data will be passed into receive_data as normal.
1384
+ #
1385
+ # Note also that this feature supports different types of descriptors: TCP, UDP, and pipes. You can relay
1386
+ # data from one kind to another, for example, feed a pipe from a UDP stream.
1387
+ #
1388
+ # @example
1389
+ #
1390
+ # module ProxyConnection
1391
+ # def initialize(client, request)
1392
+ # @client, @request = client, request
1393
+ # end
1394
+ #
1395
+ # def post_init
1396
+ # EM::enable_proxy(self, @client)
1397
+ # end
1398
+ #
1399
+ # def connection_completed
1400
+ # send_data @request
1401
+ # end
1402
+ #
1403
+ # def proxy_target_unbound
1404
+ # close_connection
1405
+ # end
1406
+ #
1407
+ # def unbind
1408
+ # @client.close_connection_after_writing
1409
+ # end
1410
+ # end
1411
+ #
1412
+ # module ProxyServer
1413
+ # def receive_data(data)
1414
+ # (@buf ||= "") << data
1415
+ # if @buf =~ /\r\n\r\n/ # all http headers received
1416
+ # EventMachine.connect("10.0.0.15", 80, ProxyConnection, self, data)
1417
+ # end
1418
+ # end
1419
+ # end
1420
+ #
1421
+ # EventMachine.run {
1422
+ # EventMachine.start_server("127.0.0.1", 8080, ProxyServer)
1423
+ # }
1424
+ #
1425
+ # @param [EventMachine::Connection] from Source of data to be proxies/streamed.
1426
+ # @param [EventMachine::Connection] to Destination of data to be proxies/streamed.
1427
+ # @param [Integer] bufsize Buffer size to use
1428
+ # @param [Integer] length Maximum number of bytes to proxy.
1429
+ #
1430
+ # @see EventMachine.disable_proxy
1431
+ def self.enable_proxy(from, to, bufsize=0, length=0)
1432
+ EM::start_proxy(from.signature, to.signature, bufsize, length)
1433
+ end
1434
+
1435
+ # Takes just one argument, a {Connection} that has proxying enabled via {EventMachine.enable_proxy}.
1436
+ # Calling this method will remove that functionality and your connection will begin receiving
1437
+ # data via {Connection#receive_data} again.
1438
+ #
1439
+ # @param [EventMachine::Connection] from Source of data that is being proxied
1440
+ # @see EventMachine.enable_proxy
1441
+ def self.disable_proxy(from)
1442
+ EM::stop_proxy(from.signature)
1443
+ end
1444
+
1445
+ # Retrieve the heartbeat interval. This is how often EventMachine will check for dead connections
1446
+ # that have had an inactivity timeout set via {Connection#set_comm_inactivity_timeout}.
1447
+ # Default is 2 seconds.
1448
+ #
1449
+ # @return [Integer] Heartbeat interval, in seconds
1450
+ def self.heartbeat_interval
1451
+ EM::get_heartbeat_interval
1452
+ end
1453
+
1454
+ # Set the heartbeat interval. This is how often EventMachine will check for dead connections
1455
+ # that have had an inactivity timeout set via {Connection#set_comm_inactivity_timeout}.
1456
+ # Takes a Numeric number of seconds. Default is 2.
1457
+ #
1458
+ # @param [Integer] time Heartbeat interval, in seconds
1459
+ def self.heartbeat_interval=(time)
1460
+ EM::set_heartbeat_interval time.to_f
1461
+ end
1462
+
1463
+ # @private
1464
+ def self.event_callback conn_binding, opcode, data
1465
+ #
1466
+ # Changed 27Dec07: Eliminated the hookable error handling.
1467
+ # No one was using it, and it degraded performance significantly.
1468
+ # It's in original_event_callback, which is dead code.
1469
+ #
1470
+ # Changed 25Jul08: Added a partial solution to the problem of exceptions
1471
+ # raised in user-written event-handlers. If such exceptions are not caught,
1472
+ # we must cause the reactor to stop, and then re-raise the exception.
1473
+ # Otherwise, the reactor doesn't stop and it's left on the call stack.
1474
+ # This is partial because we only added it to #unbind, where it's critical
1475
+ # (to keep unbind handlers from being re-entered when a stopping reactor
1476
+ # runs down open connections). It should go on the other calls to user
1477
+ # code, but the performance impact may be too large.
1478
+ #
1479
+ if opcode == ConnectionUnbound
1480
+ if c = @conns.delete( conn_binding )
1481
+ begin
1482
+ if c.original_method(:unbind).arity != 0
1483
+ c.unbind(data == 0 ? nil : EventMachine::ERRNOS[data])
1484
+ else
1485
+ c.unbind
1486
+ end
1487
+ # If this is an attached (but not watched) connection, close the underlying io object.
1488
+ if c.instance_variable_defined?(:@io) and !c.instance_variable_get(:@watch_mode)
1489
+ io = c.instance_variable_get(:@io)
1490
+ begin
1491
+ io.close
1492
+ rescue Errno::EBADF, IOError
1493
+ end
1494
+ end
1495
+ # As noted above, unbind absolutely must not raise an exception or the reactor will crash.
1496
+ # If there is no EM.error_handler, or if the error_handler retrows, then stop the reactor,
1497
+ # stash the exception in $wrapped_exception, and the exception will be raised after the
1498
+ # reactor is cleaned up (see the last line of self.run).
1499
+ rescue Exception => error
1500
+ if instance_variable_defined? :@error_handler
1501
+ begin
1502
+ @error_handler.call error
1503
+ # No need to stop unless error_handler rethrows
1504
+ rescue Exception => error
1505
+ @wrapped_exception = error
1506
+ stop
1507
+ end
1508
+ else
1509
+ @wrapped_exception = error
1510
+ stop
1511
+ end
1512
+ end
1513
+ elsif c = @acceptors.delete( conn_binding )
1514
+ # no-op
1515
+ else
1516
+ if $! # Bubble user generated errors.
1517
+ @wrapped_exception = $!
1518
+ stop
1519
+ else
1520
+ raise ConnectionNotBound, "received ConnectionUnbound for an unknown signature: #{conn_binding}"
1521
+ end
1522
+ end
1523
+ elsif opcode == ConnectionAccepted
1524
+ accep,args,blk = @acceptors[conn_binding]
1525
+ raise NoHandlerForAcceptedConnection unless accep
1526
+ c = accep.new data, *args
1527
+ @conns[data] = c
1528
+ blk and blk.call(c)
1529
+ c # (needed?)
1530
+ ##
1531
+ # The remaining code is a fallback for the pure ruby and java reactors.
1532
+ # In the C++ reactor, these events are handled in the C event_callback() in rubymain.cpp
1533
+ elsif opcode == ConnectionCompleted
1534
+ c = @conns[conn_binding] or raise ConnectionNotBound, "received ConnectionCompleted for unknown signature: #{conn_binding}"
1535
+ c.connection_completed
1536
+ elsif opcode == SslHandshakeCompleted
1537
+ c = @conns[conn_binding] or raise ConnectionNotBound, "received SslHandshakeCompleted for unknown signature: #{conn_binding}"
1538
+ c.ssl_handshake_completed
1539
+ elsif opcode == SslVerify
1540
+ c = @conns[conn_binding] or raise ConnectionNotBound, "received SslVerify for unknown signature: #{conn_binding}"
1541
+ c.close_connection if c.ssl_verify_peer(data) == false
1542
+ elsif opcode == TimerFired
1543
+ t = @timers.delete( data )
1544
+ return if t == false # timer cancelled
1545
+ t or raise UnknownTimerFired, "timer data: #{data}"
1546
+ t.call
1547
+ elsif opcode == ConnectionData
1548
+ c = @conns[conn_binding] or raise ConnectionNotBound, "received data #{data} for unknown signature: #{conn_binding}"
1549
+ c.receive_data data
1550
+ elsif opcode == LoopbreakSignalled
1551
+ run_deferred_callbacks
1552
+ elsif opcode == ConnectionNotifyReadable
1553
+ c = @conns[conn_binding] or raise ConnectionNotBound
1554
+ c.notify_readable
1555
+ elsif opcode == ConnectionNotifyWritable
1556
+ c = @conns[conn_binding] or raise ConnectionNotBound
1557
+ c.notify_writable
1558
+ end
1559
+ end
1560
+
1561
+ #
1562
+ #
1563
+ # @private
1564
+ def self._open_file_for_writing filename, handler=nil
1565
+ klass = klass_from_handler(Connection, handler)
1566
+
1567
+ s = _write_file filename
1568
+ c = klass.new s
1569
+ @conns[s] = c
1570
+ block_given? and yield c
1571
+ c
1572
+ end
1573
+
1574
+ # @private
1575
+ def self.klass_from_handler(klass = Connection, handler = nil, *args)
1576
+ klass = if handler and handler.is_a?(Class)
1577
+ raise ArgumentError, "must provide module or subclass of #{klass.name}" unless klass >= handler
1578
+ handler
1579
+ elsif handler
1580
+ if defined?(handler::EM_CONNECTION_CLASS)
1581
+ handler::EM_CONNECTION_CLASS
1582
+ else
1583
+ handler::const_set(:EM_CONNECTION_CLASS, Class.new(klass) {include handler})
1584
+ end
1585
+ else
1586
+ klass
1587
+ end
1588
+
1589
+ arity = klass.instance_method(:initialize).arity
1590
+ expected = arity >= 0 ? arity : -(arity + 1)
1591
+ if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
1592
+ raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
1593
+ end
1594
+
1595
+ klass
1596
+ end
1597
+ end # module EventMachine
1598
+
1599
+ # Alias for {EventMachine}
1600
+ EM = EventMachine
1601
+ # Alias for {EventMachine::Protocols}
1602
+ EM::P = EventMachine::Protocols