sonixlabs-eventmachine-java 1.0.0.rc.4-java

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