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