careo-eventmachine 0.12.5.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 (125) hide show
  1. data/Rakefile +191 -0
  2. data/docs/COPYING +60 -0
  3. data/docs/ChangeLog +183 -0
  4. data/docs/DEFERRABLES +138 -0
  5. data/docs/EPOLL +141 -0
  6. data/docs/GNU +281 -0
  7. data/docs/INSTALL +15 -0
  8. data/docs/KEYBOARD +38 -0
  9. data/docs/LEGAL +25 -0
  10. data/docs/LIGHTWEIGHT_CONCURRENCY +72 -0
  11. data/docs/PURE_RUBY +77 -0
  12. data/docs/README +74 -0
  13. data/docs/RELEASE_NOTES +96 -0
  14. data/docs/SMTP +9 -0
  15. data/docs/SPAWNED_PROCESSES +93 -0
  16. data/docs/TODO +10 -0
  17. data/ext/binder.cpp +126 -0
  18. data/ext/binder.h +48 -0
  19. data/ext/cmain.cpp +573 -0
  20. data/ext/cplusplus.cpp +177 -0
  21. data/ext/ed.cpp +1521 -0
  22. data/ext/ed.h +379 -0
  23. data/ext/em.cpp +1926 -0
  24. data/ext/em.h +184 -0
  25. data/ext/emwin.cpp +300 -0
  26. data/ext/emwin.h +94 -0
  27. data/ext/epoll.cpp +26 -0
  28. data/ext/epoll.h +25 -0
  29. data/ext/eventmachine.h +97 -0
  30. data/ext/eventmachine_cpp.h +95 -0
  31. data/ext/extconf.rb +128 -0
  32. data/ext/fastfilereader/extconf.rb +118 -0
  33. data/ext/fastfilereader/mapper.cpp +210 -0
  34. data/ext/fastfilereader/mapper.h +59 -0
  35. data/ext/fastfilereader/rubymain.cpp +127 -0
  36. data/ext/files.cpp +94 -0
  37. data/ext/files.h +65 -0
  38. data/ext/kb.cpp +82 -0
  39. data/ext/page.cpp +107 -0
  40. data/ext/page.h +51 -0
  41. data/ext/pipe.cpp +337 -0
  42. data/ext/project.h +119 -0
  43. data/ext/rubymain.cpp +796 -0
  44. data/ext/sigs.cpp +89 -0
  45. data/ext/sigs.h +32 -0
  46. data/ext/ssl.cpp +423 -0
  47. data/ext/ssl.h +90 -0
  48. data/java/src/com/rubyeventmachine/Application.java +196 -0
  49. data/java/src/com/rubyeventmachine/Connection.java +74 -0
  50. data/java/src/com/rubyeventmachine/ConnectionFactory.java +37 -0
  51. data/java/src/com/rubyeventmachine/DefaultConnectionFactory.java +46 -0
  52. data/java/src/com/rubyeventmachine/EmReactor.java +408 -0
  53. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  54. data/java/src/com/rubyeventmachine/EventableChannel.java +57 -0
  55. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +171 -0
  56. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +244 -0
  57. data/java/src/com/rubyeventmachine/PeriodicTimer.java +38 -0
  58. data/java/src/com/rubyeventmachine/Timer.java +54 -0
  59. data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +108 -0
  60. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +124 -0
  61. data/java/src/com/rubyeventmachine/tests/EMTest.java +80 -0
  62. data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +53 -0
  63. data/java/src/com/rubyeventmachine/tests/TestServers.java +74 -0
  64. data/java/src/com/rubyeventmachine/tests/TestTimers.java +89 -0
  65. data/lib/em/deferrable.rb +208 -0
  66. data/lib/em/eventable.rb +39 -0
  67. data/lib/em/future.rb +62 -0
  68. data/lib/em/messages.rb +66 -0
  69. data/lib/em/processes.rb +68 -0
  70. data/lib/em/spawnable.rb +88 -0
  71. data/lib/em/streamer.rb +112 -0
  72. data/lib/eventmachine.rb +1852 -0
  73. data/lib/eventmachine_version.rb +31 -0
  74. data/lib/evma.rb +32 -0
  75. data/lib/evma/callback.rb +32 -0
  76. data/lib/evma/container.rb +75 -0
  77. data/lib/evma/factory.rb +77 -0
  78. data/lib/evma/protocol.rb +87 -0
  79. data/lib/evma/reactor.rb +48 -0
  80. data/lib/jeventmachine.rb +137 -0
  81. data/lib/pr_eventmachine.rb +1011 -0
  82. data/lib/protocols/buftok.rb +127 -0
  83. data/lib/protocols/header_and_content.rb +129 -0
  84. data/lib/protocols/httpcli2.rb +794 -0
  85. data/lib/protocols/httpclient.rb +270 -0
  86. data/lib/protocols/line_and_text.rb +126 -0
  87. data/lib/protocols/linetext2.rb +161 -0
  88. data/lib/protocols/postgres.rb +261 -0
  89. data/lib/protocols/saslauth.rb +179 -0
  90. data/lib/protocols/smtpclient.rb +308 -0
  91. data/lib/protocols/smtpserver.rb +556 -0
  92. data/lib/protocols/stomp.rb +153 -0
  93. data/lib/protocols/tcptest.rb +57 -0
  94. data/tasks/cpp.rake +77 -0
  95. data/tasks/project.rake +78 -0
  96. data/tasks/tests.rake +192 -0
  97. data/tests/test_attach.rb +66 -0
  98. data/tests/test_basic.rb +231 -0
  99. data/tests/test_defer.rb +47 -0
  100. data/tests/test_epoll.rb +163 -0
  101. data/tests/test_errors.rb +82 -0
  102. data/tests/test_eventables.rb +77 -0
  103. data/tests/test_exc.rb +58 -0
  104. data/tests/test_futures.rb +214 -0
  105. data/tests/test_hc.rb +218 -0
  106. data/tests/test_httpclient.rb +215 -0
  107. data/tests/test_httpclient2.rb +155 -0
  108. data/tests/test_kb.rb +65 -0
  109. data/tests/test_ltp.rb +188 -0
  110. data/tests/test_ltp2.rb +320 -0
  111. data/tests/test_next_tick.rb +102 -0
  112. data/tests/test_processes.rb +56 -0
  113. data/tests/test_pure.rb +129 -0
  114. data/tests/test_running.rb +47 -0
  115. data/tests/test_sasl.rb +74 -0
  116. data/tests/test_send_file.rb +243 -0
  117. data/tests/test_servers.rb +80 -0
  118. data/tests/test_smtpclient.rb +83 -0
  119. data/tests/test_smtpserver.rb +93 -0
  120. data/tests/test_spawn.rb +329 -0
  121. data/tests/test_ssl_args.rb +68 -0
  122. data/tests/test_timers.rb +148 -0
  123. data/tests/test_ud.rb +43 -0
  124. data/tests/testem.rb +31 -0
  125. metadata +202 -0
@@ -0,0 +1,68 @@
1
+ # $Id$
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 13 Dec 07
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-08 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+
26
+
27
+ module EventMachine
28
+
29
+ # EM::DeferrableChildProcess is a sugaring of a common use-case
30
+ # involving EM::popen.
31
+ # Call the #open method on EM::DeferrableChildProcess, passing
32
+ # a command-string. #open immediately returns an EM::Deferrable
33
+ # object. It also schedules the forking of a child process, which
34
+ # will execute the command passed to #open.
35
+ # When the forked child terminates, the Deferrable will be signalled
36
+ # and execute its callbacks, passing the data that the child process
37
+ # wrote to stdout.
38
+ #
39
+ class DeferrableChildProcess < EventMachine::Connection
40
+ include EventMachine::Deferrable
41
+
42
+ # Sugars a common use-case involving forked child processes.
43
+ # #open takes a String argument containing an shell command
44
+ # string (including arguments if desired). #open immediately
45
+ # returns an EventMachine::Deferrable object, without blocking.
46
+ #
47
+ # It also invokes EventMachine#popen to run the passed-in
48
+ # command in a forked child process.
49
+ #
50
+ # When the forked child terminates, the Deferrable that
51
+ # #open calls its callbacks, passing the data returned
52
+ # from the child process.
53
+ #
54
+ def self.open cmd
55
+ EventMachine.popen( cmd, DeferrableChildProcess )
56
+ end
57
+
58
+ def receive_data data
59
+ (@data ||= []) << data
60
+ end
61
+
62
+ def unbind
63
+ succeed( @data.join )
64
+ end
65
+ end
66
+ end
67
+
68
+
@@ -0,0 +1,88 @@
1
+ # $Id$
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 25 Aug 2007
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+
26
+
27
+ # Support for Erlang-style processes.
28
+ #
29
+
30
+
31
+ module EventMachine
32
+ class SpawnedProcess
33
+ #attr_accessor :receiver
34
+ def notify *x
35
+ me = self
36
+ EM.next_tick {
37
+ # A notification executes in the context of this
38
+ # SpawnedProcess object. That makes self and notify
39
+ # work as one would expect.
40
+ #
41
+ y = me.call(*x)
42
+ if y and y.respond_to?(:pull_out_yield_block)
43
+ a,b = y.pull_out_yield_block
44
+ set_receiver a
45
+ self.notify if b
46
+ end
47
+ }
48
+ end
49
+ alias_method :resume, :notify
50
+ alias_method :run, :notify # for formulations like (EM.spawn {xxx}).run
51
+
52
+ # I know I'm missing something stupid, but the inside of class << s
53
+ # can't see locally-bound values. It can see globals, though.
54
+ def set_receiver blk
55
+ $em______tmpglobal = blk
56
+ class << self
57
+ define_method :call, $em______tmpglobal.dup
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ class YieldBlockFromSpawnedProcess
64
+ def initialize block, notify
65
+ @block = [block,notify]
66
+ end
67
+ def pull_out_yield_block
68
+ @block
69
+ end
70
+ end
71
+
72
+ def EventMachine.spawn &block
73
+ s = SpawnedProcess.new
74
+ s.set_receiver block
75
+ s
76
+ end
77
+
78
+ def EventMachine.yield &block
79
+ return YieldBlockFromSpawnedProcess.new( block, false )
80
+ end
81
+
82
+ def EventMachine.yield_and_notify &block
83
+ return YieldBlockFromSpawnedProcess.new( block, true )
84
+ end
85
+ end
86
+
87
+
88
+
@@ -0,0 +1,112 @@
1
+ # $Id$
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 16 Jul 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+
26
+
27
+ module EventMachine
28
+ class FileStreamer
29
+ MappingThreshold = 16384
30
+ BackpressureLevel = 50000
31
+ ChunkSize = 16384
32
+
33
+ include Deferrable
34
+ def initialize connection, filename, args
35
+ @connection = connection
36
+ @http_chunks = args[:http_chunks]
37
+
38
+ if File.exist?(filename)
39
+ @size = File.size?(filename)
40
+ if @size <= MappingThreshold
41
+ stream_without_mapping filename
42
+ else
43
+ stream_with_mapping filename
44
+ end
45
+ else
46
+ fail "file not found"
47
+ end
48
+ end
49
+
50
+ def stream_without_mapping filename
51
+ if @http_chunks
52
+ @connection.send_data "#{@size.to_s(16)}\r\n"
53
+ @connection.send_file_data filename
54
+ @connection.send_data "\r\n0\r\n\r\n"
55
+ else
56
+ @connection.send_file_data filename
57
+ end
58
+ succeed
59
+ end
60
+ private :stream_without_mapping
61
+
62
+ def stream_with_mapping filename
63
+ ensure_mapping_extension_is_present
64
+
65
+ @position = 0
66
+ @mapping = EventMachine::FastFileReader::Mapper.new filename
67
+ stream_one_chunk
68
+ end
69
+ private :stream_with_mapping
70
+
71
+ def stream_one_chunk
72
+ loop {
73
+ if @position < @size
74
+ if @connection.get_outbound_data_size > BackpressureLevel
75
+ EventMachine::next_tick {stream_one_chunk}
76
+ break
77
+ else
78
+ len = @size - @position
79
+ len = ChunkSize if (len > ChunkSize)
80
+
81
+ @connection.send_data( "#{len.to_s(16)}\r\n" ) if @http_chunks
82
+ @connection.send_data( @mapping.get_chunk( @position, len ))
83
+ @connection.send_data("\r\n") if @http_chunks
84
+
85
+ @position += len
86
+ end
87
+ else
88
+ @connection.send_data "0\r\n\r\n" if @http_chunks
89
+ @mapping.close
90
+ succeed
91
+ break
92
+ end
93
+ }
94
+ end
95
+
96
+ #--
97
+ # We use an outboard extension class to get memory-mapped files.
98
+ # It's outboard to avoid polluting the core distro, but that means
99
+ # there's a "hidden" dependency on it. The first time we get here in
100
+ # any run, try to load up the dependency extension. User code will see
101
+ # a LoadError if it's not available, but code that doesn't require
102
+ # mapped files will work fine without it. This is a somewhat difficult
103
+ # compromise between usability and proper modularization.
104
+ #
105
+ def ensure_mapping_extension_is_present
106
+ @@fastfilereader ||= (require 'fastfilereaderext')
107
+ end
108
+ private :ensure_mapping_extension_is_present
109
+
110
+ end
111
+ end
112
+
@@ -0,0 +1,1852 @@
1
+ # $Id$
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 8 Apr 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+
26
+
27
+ #-- Select in a library based on a global variable.
28
+ # PROVISIONALLY commented out this whole mechanism which selects
29
+ # a pure-Ruby EM implementation if the extension is not available.
30
+ # I expect this will cause a lot of people's code to break, as it
31
+ # exposes misconfigurations and path problems that were masked up
32
+ # till now. The reason I'm disabling it is because the pure-Ruby
33
+ # code will have problems of its own, and it's not nearly as fast
34
+ # anyway. Suggested by a problem report from Moshe Litvin. 05Jun07.
35
+ #
36
+ # 05Dec07: Re-enabled the pure-ruby mechanism, but without the automatic
37
+ # fallback feature that tripped up Moshe Litvin. We shouldn't fail over to
38
+ # the pure Ruby version because it's possible that the user intended to
39
+ # run the extension but failed to do so because of a compilation or
40
+ # similar error. So we require either a global variable or an environment
41
+ # string be set in order to select the pure-Ruby version.
42
+ #
43
+
44
+
45
+ unless defined?($eventmachine_library)
46
+ $eventmachine_library = ENV['EVENTMACHINE_LIBRARY'] || :cascade
47
+ end
48
+ $eventmachine_library = $eventmachine_library.to_sym
49
+
50
+ case $eventmachine_library
51
+ when :pure_ruby
52
+ require 'pr_eventmachine'
53
+ when :extension
54
+ require 'rubyeventmachine'
55
+ when :java
56
+ require 'jeventmachine'
57
+ else # :cascade
58
+ # This is the case that most user code will take.
59
+ # Prefer the extension if available.
60
+ begin
61
+ if RUBY_PLATFORM =~ /java/
62
+ require 'java'
63
+ require 'jeventmachine'
64
+ $eventmachine_library = :java
65
+ else
66
+ require 'rubyeventmachine'
67
+ $eventmachine_library = :extension
68
+ end
69
+ rescue LoadError
70
+ warn "# EventMachine fell back to pure ruby mode" if $DEBUG
71
+ require 'pr_eventmachine'
72
+ $eventmachine_library = :pure_ruby
73
+ end
74
+ end
75
+
76
+ require "eventmachine_version"
77
+ require 'em/deferrable'
78
+ require 'em/future'
79
+ require 'em/eventable'
80
+ require 'em/messages'
81
+ require 'em/streamer'
82
+ require 'em/spawnable'
83
+
84
+ require 'shellwords'
85
+
86
+ #-- Additional requires are at the BOTTOM of this file, because they
87
+ #-- depend on stuff defined in here. Refactor that someday.
88
+
89
+
90
+
91
+ # == Introduction
92
+ # EventMachine provides a fast, lightweight framework for implementing
93
+ # Ruby programs that can use the network to communicate with other
94
+ # processes. Using EventMachine, Ruby programmers can easily connect
95
+ # to remote servers and act as servers themselves. EventMachine does not
96
+ # supplant the Ruby IP libraries. It does provide an alternate technique
97
+ # for those applications requiring better performance, scalability,
98
+ # and discipline over the behavior of network sockets, than is easily
99
+ # obtainable using the built-in libraries, especially in applications
100
+ # which are structurally well-suited for the event-driven programming model.
101
+ #
102
+ # EventMachine provides a perpetual event-loop which your programs can
103
+ # start and stop. Within the event loop, TCP network connections are
104
+ # initiated and accepted, based on EventMachine methods called by your
105
+ # program. You also define callback methods which are called by EventMachine
106
+ # when events of interest occur within the event-loop.
107
+ #
108
+ # User programs will be called back when the following events occur:
109
+ # * When the event loop accepts network connections from remote peers
110
+ # * When data is received from network connections
111
+ # * When connections are closed, either by the local or the remote side
112
+ # * When user-defined timers expire
113
+ #
114
+ # == Usage example
115
+ #
116
+ # Here's a fully-functional echo server implemented in EventMachine:
117
+ #
118
+ # require 'rubygems'
119
+ # require 'eventmachine'
120
+ #
121
+ # module EchoServer
122
+ # def receive_data data
123
+ # send_data ">>>you sent: #{data}"
124
+ # close_connection if data =~ /quit/i
125
+ # end
126
+ # end
127
+ #
128
+ # EventMachine::run {
129
+ # EventMachine::start_server "192.168.0.100", 8081, EchoServer
130
+ # }
131
+ #
132
+ # What's going on here? Well, we have defined the module EchoServer to
133
+ # implement the semantics of the echo protocol (more about that shortly).
134
+ # The last three lines invoke the event-machine itself, which runs forever
135
+ # unless one of your callbacks terminates it. The block that you supply
136
+ # to EventMachine::run contains code that runs immediately after the event
137
+ # machine is initialized and before it starts looping. This is the place
138
+ # to open up a TCP server by specifying the address and port it will listen
139
+ # on, together with the module that will process the data.
140
+ #
141
+ # Our EchoServer is extremely simple as the echo protocol doesn't require
142
+ # much work. Basically you want to send back to the remote peer whatever
143
+ # data it sends you. We'll dress it up with a little extra text to make it
144
+ # interesting. Also, we'll close the connection in case the received data
145
+ # contains the word "quit."
146
+ #
147
+ # So what about this module EchoServer? Well, whenever a network connection
148
+ # (either a client or a server) starts up, EventMachine instantiates an anonymous
149
+ # class, that your module has been mixed into. Exactly one of these class
150
+ # instances is created for each connection. Whenever an event occurs on a
151
+ # given connection, its corresponding object automatically calls specific
152
+ # instance methods which your module may redefine. The code in your module
153
+ # always runs in the context of a class instance, so you can create instance
154
+ # variables as you wish and they will be carried over to other callbacks
155
+ # made on that same connection.
156
+ #
157
+ # Looking back up at EchoServer, you can see that we've defined the method
158
+ # receive_data which (big surprise) is called whenever data has been received
159
+ # from the remote end of the connection. Very simple. We get the data
160
+ # (a String object) and can do whatever we wish with it. In this case,
161
+ # we use the method send_data to return the received data to the caller,
162
+ # with some extra text added in. And if the user sends the word "quit,"
163
+ # we'll close the connection with (naturally) close_connection.
164
+ # (Notice that closing the connection doesn't terminate the processing loop,
165
+ # or change the fact that your echo server is still accepting connections!)
166
+ #
167
+ #
168
+ # == Questions and Futures
169
+ # Would it be useful for EventMachine to incorporate the Observer pattern
170
+ # and make use of the corresponding Ruby <tt>observer</tt> package?
171
+ # Interesting thought.
172
+ #
173
+ #
174
+ module EventMachine
175
+ class FileNotFoundException < Exception; end
176
+
177
+ class << self
178
+ attr_reader :threadpool
179
+ end
180
+
181
+
182
+ # EventMachine::run initializes and runs an event loop.
183
+ # This method only returns if user-callback code calls stop_event_loop.
184
+ # Use the supplied block to define your clients and servers.
185
+ # The block is called by EventMachine::run immediately after initializing
186
+ # its internal event loop but <i>before</i> running the loop.
187
+ # Therefore this block is the right place to call start_server if you
188
+ # want to accept connections from remote clients.
189
+ #
190
+ # For programs that are structured as servers, it's usually appropriate
191
+ # to start an event loop by calling EventMachine::run, and let it
192
+ # run forever. It's also possible to use EventMachine::run to make a single
193
+ # client-connection to a remote server, process the data flow from that
194
+ # single connection, and then call stop_event_loop to force EventMachine::run
195
+ # to return. Your program will then continue from the point immediately
196
+ # following the call to EventMachine::run.
197
+ #
198
+ # You can of course do both client and servers simultaneously in the same program.
199
+ # One of the strengths of the event-driven programming model is that the
200
+ # handling of network events on many different connections will be interleaved,
201
+ # and scheduled according to the actual events themselves. This maximizes
202
+ # efficiency.
203
+ #
204
+ # === Server usage example
205
+ #
206
+ # See the text at the top of this file for an example of an echo server.
207
+ #
208
+ # === Client usage example
209
+ #
210
+ # See the description of stop_event_loop for an extremely simple client example.
211
+ #
212
+ #--
213
+ # Obsoleted the use_threads mechanism.
214
+ # 25Nov06: Added the begin/ensure block. We need to be sure that release_machine
215
+ # gets called even if an exception gets thrown within any of the user code
216
+ # that the event loop runs. The best way to see this is to run a unit
217
+ # test with two functions, each of which calls EventMachine#run and each of
218
+ # which throws something inside of #run. Without the ensure, the second test
219
+ # will start without release_machine being called and will immediately throw
220
+ # a C++ runtime error.
221
+ #
222
+ def EventMachine::run blk=nil, tail=nil, &block
223
+ @tails ||= []
224
+ tail and @tails.unshift(tail)
225
+
226
+ if reactor_running?
227
+ (b = blk || block) and b.call # next_tick(b)
228
+ else
229
+ @conns = {}
230
+ @acceptors = {}
231
+ @timers = {}
232
+ @wrapped_exception = nil
233
+ begin
234
+ @reactor_running = true
235
+ initialize_event_machine
236
+ (b = blk || block) and add_timer(0, b)
237
+ run_machine
238
+ ensure
239
+ begin
240
+ release_machine
241
+ ensure
242
+ if @threadpool
243
+ @threadpool.each { |t| t.exit }
244
+ @threadpool.each { |t| t.kill! if t.alive? }
245
+ @threadqueue = nil
246
+ @resultqueue = nil
247
+ end
248
+ @threadpool = nil
249
+ end
250
+ @reactor_running = false
251
+ end
252
+
253
+ until @tails.empty?
254
+ @tails.pop.call
255
+ end
256
+
257
+ raise @wrapped_exception if @wrapped_exception
258
+ end
259
+ end
260
+
261
+
262
+ # Sugars a common use case. Will pass the given block to #run, but will terminate
263
+ # the reactor loop and exit the function as soon as the code in the block completes.
264
+ # (Normally, #run keeps running indefinitely, even after the block supplied to it
265
+ # finishes running, until user code calls #stop.)
266
+ #
267
+ def EventMachine::run_block &block
268
+ pr = proc {
269
+ block.call
270
+ EventMachine::stop
271
+ }
272
+ run(&pr)
273
+ end
274
+
275
+ # fork_reactor forks a new process and calls EM#run inside of it, passing your block.
276
+ #--
277
+ # This implementation is subject to change, especially if we clean up the relationship
278
+ # of EM#run to @reactor_running.
279
+ # Original patch by Aman Gupta.
280
+ #
281
+ def EventMachine::fork_reactor &block
282
+ Kernel.fork do
283
+ if self.reactor_running?
284
+ self.stop_event_loop
285
+ self.release_machine
286
+ self.instance_variable_set( '@reactor_running', false )
287
+ end
288
+ self.run block
289
+ end
290
+ end
291
+
292
+
293
+ # +deprecated+
294
+ #--
295
+ # EventMachine#run_without_threads is semantically identical
296
+ # to EventMachine#run, but it runs somewhat faster.
297
+ # However, it must not be used in applications that spin
298
+ # Ruby threads.
299
+ def EventMachine::run_without_threads &block
300
+ #EventMachine::run false, &block
301
+ EventMachine::run(&block)
302
+ end
303
+
304
+ # EventMachine#add_timer adds a one-shot timer to the event loop.
305
+ # Call it with one or two parameters. The first parameters is a delay-time
306
+ # expressed in <i>seconds</i> (not milliseconds). The second parameter, if
307
+ # present, must be a proc object. If a proc object is not given, then you
308
+ # can also simply pass a block to the method call.
309
+ #
310
+ # EventMachine#add_timer may be called from the block passed to EventMachine#run
311
+ # or from any callback method. It schedules execution of the proc or block
312
+ # passed to add_timer, after the passage of an interval of time equal to
313
+ # <i>at least</i> the number of seconds specified in the first parameter to
314
+ # the call.
315
+ #
316
+ # EventMachine#add_timer is a <i>non-blocking</i> call. Callbacks can and will
317
+ # be called during the interval of time that the timer is in effect.
318
+ # There is no built-in limit to the number of timers that can be outstanding at
319
+ # any given time.
320
+ #
321
+ # === Usage example
322
+ #
323
+ # This example shows how easy timers are to use. Observe that two timers are
324
+ # initiated simultaneously. Also, notice that the event loop will continue
325
+ # to run even after the second timer event is processed, since there was
326
+ # no call to EventMachine#stop_event_loop. There will be no activity, of
327
+ # course, since no network clients or servers are defined. Stop the program
328
+ # with Ctrl-C.
329
+ #
330
+ # require 'rubygems'
331
+ # require 'eventmachine'
332
+ #
333
+ # EventMachine::run {
334
+ # puts "Starting the run now: #{Time.now}"
335
+ # EventMachine::add_timer 5, proc { puts "Executing timer event: #{Time.now}" }
336
+ # EventMachine::add_timer( 10 ) { puts "Executing timer event: #{Time.now}" }
337
+ # }
338
+ #
339
+ #
340
+ #--
341
+ # Changed 04Oct06: We now pass the interval as an integer number of milliseconds.
342
+ #
343
+ def EventMachine::add_timer *args, &block
344
+ interval = args.shift
345
+ code = args.shift || block
346
+ if code
347
+ # check too many timers!
348
+ s = add_oneshot_timer((interval * 1000).to_i)
349
+ @timers[s] = code
350
+ s
351
+ end
352
+ end
353
+
354
+ # EventMachine#add_periodic_timer adds a periodic timer to the event loop.
355
+ # It takes the same parameters as the one-shot timer method, EventMachine#add_timer.
356
+ # This method schedules execution of the given block repeatedly, at intervals
357
+ # of time <i>at least</i> as great as the number of seconds given in the first
358
+ # parameter to the call.
359
+ #
360
+ # === Usage example
361
+ #
362
+ # The following sample program will write a dollar-sign to stderr every five seconds.
363
+ # (Of course if the program defined network clients and/or servers, they would
364
+ # be doing their work while the periodic timer is counting off.)
365
+ #
366
+ # EventMachine::run {
367
+ # EventMachine::add_periodic_timer( 5 ) { $stderr.write "$" }
368
+ # }
369
+ #
370
+ def EventMachine::add_periodic_timer *args, &block
371
+ interval = args.shift
372
+ code = args.shift || block
373
+ if code
374
+ block_1 = proc {
375
+ code.call
376
+ EventMachine::add_periodic_timer interval, code
377
+ }
378
+ add_timer interval, block_1
379
+ end
380
+ end
381
+
382
+ #--
383
+ #
384
+ def EventMachine::cancel_timer signature
385
+ @timers[signature] = proc{} if @timers.has_key?(signature)
386
+ end
387
+
388
+
389
+ # stop_event_loop may called from within a callback method
390
+ # while EventMachine's processing loop is running.
391
+ # It causes the processing loop to stop executing, which
392
+ # will cause all open connections and accepting servers
393
+ # to be run down and closed. <i>Callbacks for connection-termination
394
+ # will be called</i> as part of the processing of stop_event_loop.
395
+ # (There currently is no option to panic-stop the loop without
396
+ # closing connections.) When all of this processing is complete,
397
+ # the call to EventMachine::run which started the processing loop
398
+ # will return and program flow will resume from the statement
399
+ # following EventMachine::run call.
400
+ #
401
+ # === Usage example
402
+ #
403
+ # require 'rubygems'
404
+ # require 'eventmachine'
405
+ #
406
+ # module Redmond
407
+ #
408
+ # def post_init
409
+ # puts "We're sending a dumb HTTP request to the remote peer."
410
+ # send_data "GET / HTTP/1.1\r\nHost: www.microsoft.com\r\n\r\n"
411
+ # end
412
+ #
413
+ # def receive_data data
414
+ # puts "We received #{data.length} bytes from the remote peer."
415
+ # puts "We're going to stop the event loop now."
416
+ # EventMachine::stop_event_loop
417
+ # end
418
+ #
419
+ # def unbind
420
+ # puts "A connection has terminated."
421
+ # end
422
+ #
423
+ # end
424
+ #
425
+ # puts "We're starting the event loop now."
426
+ # EventMachine::run {
427
+ # EventMachine::connect "www.microsoft.com", 80, Redmond
428
+ # }
429
+ # puts "The event loop has stopped."
430
+ #
431
+ # This program will produce approximately the following output:
432
+ #
433
+ # We're starting the event loop now.
434
+ # We're sending a dumb HTTP request to the remote peer.
435
+ # We received 1440 bytes from the remote peer.
436
+ # We're going to stop the event loop now.
437
+ # A connection has terminated.
438
+ # The event loop has stopped.
439
+ #
440
+ #
441
+ def EventMachine::stop_event_loop
442
+ EventMachine::stop
443
+ end
444
+
445
+ # EventMachine::start_server initiates a TCP server (socket
446
+ # acceptor) on the specified IP address and port.
447
+ # The IP address must be valid on the machine where the program
448
+ # runs, and the process must be privileged enough to listen
449
+ # on the specified port (on Unix-like systems, superuser privileges
450
+ # are usually required to listen on any port lower than 1024).
451
+ # Only one listener may be running on any given address/port
452
+ # combination. start_server will fail if the given address and port
453
+ # are already listening on the machine, either because of a prior call
454
+ # to start_server or some unrelated process running on the machine.
455
+ # If start_server succeeds, the new network listener becomes active
456
+ # immediately and starts accepting connections from remote peers,
457
+ # and these connections generate callback events that are processed
458
+ # by the code specified in the handler parameter to start_server.
459
+ #
460
+ # The optional handler which is passed to start_server is the key
461
+ # to EventMachine's ability to handle particular network protocols.
462
+ # The handler parameter passed to start_server must be a Ruby Module
463
+ # that you must define. When the network server that is started by
464
+ # start_server accepts a new connection, it instantiates a new
465
+ # object of an anonymous class that is inherited from EventMachine::Connection,
466
+ # <i>into which the methods from your handler have been mixed.</i>
467
+ # Your handler module may redefine any of the methods in EventMachine::Connection
468
+ # in order to implement the specific behavior of the network protocol.
469
+ #
470
+ # Callbacks invoked in response to network events <i>always</i> take place
471
+ # within the execution context of the object derived from EventMachine::Connection
472
+ # extended by your handler module. There is one object per connection, and
473
+ # all of the callbacks invoked for a particular connection take the form
474
+ # of instance methods called against the corresponding EventMachine::Connection
475
+ # object. Therefore, you are free to define whatever instance variables you
476
+ # wish, in order to contain the per-connection state required by the network protocol you are
477
+ # implementing.
478
+ #
479
+ # start_server is often called inside the block passed to EventMachine::run,
480
+ # but it can be called from any EventMachine callback. start_server will fail
481
+ # unless the EventMachine event loop is currently running (which is why
482
+ # it's often called in the block suppled to EventMachine::run).
483
+ #
484
+ # You may call start_server any number of times to start up network
485
+ # listeners on different address/port combinations. The servers will
486
+ # all run simultaneously. More interestingly, each individual call to start_server
487
+ # can specify a different handler module and thus implement a different
488
+ # network protocol from all the others.
489
+ #
490
+ # === Usage example
491
+ # Here is an example of a server that counts lines of input from the remote
492
+ # peer and sends back the total number of lines received, after each line.
493
+ # Try the example with more than one client connection opened via telnet,
494
+ # and you will see that the line count increments independently on each
495
+ # of the client connections. Also very important to note, is that the
496
+ # handler for the receive_data function, which our handler redefines, may
497
+ # not assume that the data it receives observes any kind of message boundaries.
498
+ # Also, to use this example, be sure to change the server and port parameters
499
+ # to the start_server call to values appropriate for your environment.
500
+ #
501
+ # require 'rubygems'
502
+ # require 'eventmachine'
503
+ #
504
+ # module LineCounter
505
+ #
506
+ # MaxLinesPerConnection = 10
507
+ #
508
+ # def post_init
509
+ # puts "Received a new connection"
510
+ # @data_received = ""
511
+ # @line_count = 0
512
+ # end
513
+ #
514
+ # def receive_data data
515
+ # @data_received << data
516
+ # while @data_received.slice!( /^[^\n]*[\n]/m )
517
+ # @line_count += 1
518
+ # send_data "received #{@line_count} lines so far\r\n"
519
+ # @line_count == MaxLinesPerConnection and close_connection_after_writing
520
+ # end
521
+ # end
522
+ #
523
+ # end # module LineCounter
524
+ #
525
+ # EventMachine::run {
526
+ # host,port = "192.168.0.100", 8090
527
+ # EventMachine::start_server host, port, LineCounter
528
+ # puts "Now accepting connections on address #{host}, port #{port}..."
529
+ # EventMachine::add_periodic_timer( 10 ) { $stderr.write "*" }
530
+ # }
531
+ #
532
+ #
533
+ def EventMachine::start_server server, port=nil, handler=nil, *args, &block
534
+
535
+ begin
536
+ port = Integer(port)
537
+ rescue ArgumentError, TypeError
538
+ args.unshift handler if handler
539
+ handler = port
540
+ port = nil
541
+ end if port
542
+
543
+ klass = if (handler and handler.is_a?(Class))
544
+ handler
545
+ else
546
+ Class.new( Connection ) {handler and include handler}
547
+ end
548
+
549
+ arity = klass.instance_method(:initialize).arity
550
+ expected = arity >= 0 ? arity : -(arity + 1)
551
+ if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
552
+ raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
553
+ end
554
+
555
+ s = if port
556
+ start_tcp_server server, port
557
+ else
558
+ start_unix_server server
559
+ end
560
+ @acceptors[s] = [klass,args,block]
561
+ s
562
+ end
563
+
564
+
565
+ # Stop a TCP server socket that was started with EventMachine#start_server.
566
+ #--
567
+ # Requested by Kirk Haines. TODO, this isn't OOP enough. We ought somehow
568
+ # to have #start_server return an object that has a close or a stop method on it.
569
+ #
570
+ def EventMachine::stop_server signature
571
+ EventMachine::stop_tcp_server signature
572
+ end
573
+
574
+ def EventMachine::start_unix_domain_server filename, *args, &block
575
+ start_server filename, *args, &block
576
+ end
577
+
578
+ # EventMachine#connect initiates a TCP connection to a remote
579
+ # server and sets up event-handling for the connection.
580
+ # You can call EventMachine#connect in the block supplied
581
+ # to EventMachine#run or in any callback method.
582
+ #
583
+ # EventMachine#connect takes the IP address (or hostname) and
584
+ # port of the remote server you want to connect to.
585
+ # It also takes an optional handler Module which you must define, that
586
+ # contains the callbacks that will be invoked by the event loop
587
+ # on behalf of the connection.
588
+ #
589
+ # See the description of EventMachine#start_server for a discussion
590
+ # of the handler Module. All of the details given in that description
591
+ # apply for connections created with EventMachine#connect.
592
+ #
593
+ # === Usage Example
594
+ #
595
+ # Here's a program which connects to a web server, sends a naive
596
+ # request, parses the HTTP header of the response, and then
597
+ # (antisocially) ends the event loop, which automatically drops the connection
598
+ # (and incidentally calls the connection's unbind method).
599
+ #
600
+ # require 'rubygems'
601
+ # require 'eventmachine'
602
+ #
603
+ # module DumbHttpClient
604
+ #
605
+ # def post_init
606
+ # send_data "GET / HTTP/1.1\r\nHost: _\r\n\r\n"
607
+ # @data = ""
608
+ # end
609
+ #
610
+ # def receive_data data
611
+ # @data << data
612
+ # if @data =~ /[\n][\r]*[\n]/m
613
+ # puts "RECEIVED HTTP HEADER:"
614
+ # $`.each {|line| puts ">>> #{line}" }
615
+ #
616
+ # puts "Now we'll terminate the loop, which will also close the connection"
617
+ # EventMachine::stop_event_loop
618
+ # end
619
+ # end
620
+ #
621
+ # def unbind
622
+ # puts "A connection has terminated"
623
+ # end
624
+ #
625
+ # end # DumbHttpClient
626
+ #
627
+ #
628
+ # EventMachine::run {
629
+ # EventMachine::connect "www.bayshorenetworks.com", 80, DumbHttpClient
630
+ # }
631
+ # puts "The event loop has ended"
632
+ #
633
+ #
634
+ # There are times when it's more convenient to define a protocol handler
635
+ # as a Class rather than a Module. Here's how to do this:
636
+ #
637
+ # class MyProtocolHandler < EventMachine::Connection
638
+ # def initialize *args
639
+ # super
640
+ # # whatever else you want to do here
641
+ # end
642
+ #
643
+ # #.......your other class code
644
+ # end # class MyProtocolHandler
645
+ #
646
+ # If you do this, then an instance of your class will be instantiated to handle
647
+ # every network connection created by your code or accepted by servers that you
648
+ # create. If you redefine #post_init in your protocol-handler class, your
649
+ # #post_init method will be called _inside_ the call to #super that you will
650
+ # make in your #initialize method (if you provide one).
651
+ #
652
+ #--
653
+ # EventMachine::connect initiates a TCP connection to a remote
654
+ # server and sets up event-handling for the connection.
655
+ # It internally creates an object that should not be handled
656
+ # by the caller. HOWEVER, it's often convenient to get the
657
+ # object to set up interfacing to other objects in the system.
658
+ # We return the newly-created anonymous-class object to the caller.
659
+ # It's expected that a considerable amount of code will depend
660
+ # on this behavior, so don't change it.
661
+ #
662
+ # Ok, added support for a user-defined block, 13Apr06.
663
+ # This leads us to an interesting choice because of the
664
+ # presence of the post_init call, which happens in the
665
+ # initialize method of the new object. We call the user's
666
+ # block and pass the new object to it. This is a great
667
+ # way to do protocol-specific initiation. It happens
668
+ # AFTER post_init has been called on the object, which I
669
+ # certainly hope is the right choice.
670
+ # Don't change this lightly, because accepted connections
671
+ # are different from connected ones and we don't want
672
+ # to have them behave differently with respect to post_init
673
+ # if at all possible.
674
+ #
675
+ def EventMachine::connect server, port=nil, handler=nil, *args
676
+ begin
677
+ port = Integer(port)
678
+ rescue ArgumentError, TypeError
679
+ args.unshift handler if handler
680
+ handler = port
681
+ port = nil
682
+ end if port
683
+
684
+ klass = if (handler and handler.is_a?(Class))
685
+ handler
686
+ else
687
+ Class.new( Connection ) {handler and include handler}
688
+ end
689
+
690
+ arity = klass.instance_method(:initialize).arity
691
+ expected = arity >= 0 ? arity : -(arity + 1)
692
+ if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
693
+ raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
694
+ end
695
+
696
+ s = if port
697
+ connect_server server, port
698
+ else
699
+ connect_unix_server server
700
+ end
701
+
702
+ c = klass.new s, *args
703
+ @conns[s] = c
704
+ block_given? and yield c
705
+ c
706
+ end
707
+
708
+ # EventMachine::attach registers a given file descriptor or IO object with the eventloop
709
+ #
710
+ # If the handler provided has the functions notify_readable or notify_writable defined,
711
+ # EventMachine will not read or write from the socket, and instead fire the corresponding
712
+ # callback on the handler.
713
+ #
714
+ # To detach the file descriptor, use EventMachine::Connection#detach
715
+ #
716
+ # === Usage Example
717
+ #
718
+ # module SimpleHttpClient
719
+ # def initialize sock
720
+ # @sock = sock
721
+ # end
722
+ #
723
+ # def notify_readable
724
+ # header = @sock.readline
725
+ #
726
+ # if header == "\r\n"
727
+ # # detach returns the file descriptor number (fd == @sock.fileno)
728
+ # fd = detach
729
+ # end
730
+ # rescue EOFError
731
+ # detach
732
+ # end
733
+ #
734
+ # def unbind
735
+ # EM.next_tick do
736
+ # # socket is detached from the eventloop, but still open
737
+ # data = @sock.read
738
+ # end
739
+ # end
740
+ # end
741
+ #
742
+ # EM.run{
743
+ # $sock = TCPSocket.new('site.com', 80)
744
+ # $sock.write("GET / HTTP/1.0\r\n\r\n")
745
+ # EM.attach $sock, SimpleHttpClient, $sock
746
+ # }
747
+ #
748
+ #--
749
+ # Thanks to Riham Aldakkak (eSpace Technologies) for the initial patch
750
+ def EventMachine::attach io, handler=nil, *args
751
+ klass = if (handler and handler.is_a?(Class))
752
+ handler
753
+ else
754
+ Class.new( Connection ) {handler and include handler}
755
+ end
756
+
757
+ arity = klass.instance_method(:initialize).arity
758
+ expected = arity >= 0 ? arity : -(arity + 1)
759
+ if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
760
+ raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
761
+ end
762
+
763
+ readmode = klass.public_instance_methods.any?{|m| m.to_sym == :notify_readable }
764
+ writemode = klass.public_instance_methods.any?{|m| m.to_sym == :notify_writable }
765
+
766
+ s = attach_fd io.respond_to?(:fileno) ? io.fileno : io, readmode, writemode
767
+
768
+ c = klass.new s, *args
769
+ @conns[s] = c
770
+ block_given? and yield c
771
+ c
772
+ end
773
+
774
+ #--
775
+ # EXPERIMENTAL. DO NOT RELY ON THIS METHOD TO BE HERE IN THIS FORM, OR AT ALL.
776
+ # (03Nov06)
777
+ # Observe, the test for already-connected FAILS if we call a reconnect inside post_init,
778
+ # because we haven't set up the connection in @conns by that point.
779
+ # RESIST THE TEMPTATION to "fix" this problem by redefining the behavior of post_init.
780
+ #
781
+ # Changed 22Nov06: if called on an already-connected handler, just return the
782
+ # handler and do nothing more. Originally this condition raised an exception.
783
+ # We may want to change it yet again and call the block, if any.
784
+ #
785
+ def EventMachine::reconnect server, port, handler
786
+ raise "invalid handler" unless handler.respond_to?(:connection_completed)
787
+ #raise "still connected" if @conns.has_key?(handler.signature)
788
+ return handler if @conns.has_key?(handler.signature)
789
+ s = connect_server server, port
790
+ handler.signature = s
791
+ @conns[s] = handler
792
+ block_given? and yield handler
793
+ handler
794
+ end
795
+
796
+
797
+
798
+
799
+ # Make a connection to a Unix-domain socket. This is not implemented on Windows platforms.
800
+ # The parameter socketname is a String which identifies the Unix-domain socket you want
801
+ # to connect to. socketname is the name of a file on your local system, and in most cases
802
+ # is a fully-qualified path name. Make sure that your process has enough local permissions
803
+ # to open the Unix-domain socket.
804
+ # See also the documentation for #connect_server. This method behaves like #connect_server
805
+ # in all respects except for the fact that it connects to a local Unix-domain
806
+ # socket rather than a TCP socket.
807
+ # NOTE: this functionality will soon be subsumed into the #connect method. This method
808
+ # will still be supported as an alias.
809
+ #--
810
+ # For making connections to Unix-domain sockets.
811
+ # Eventually this has to get properly documented and unified with the TCP-connect methods.
812
+ # Note how nearly identical this is to EventMachine#connect
813
+ def EventMachine::connect_unix_domain socketname, *args, &blk
814
+ connect socketname, *args, &blk
815
+ end
816
+
817
+
818
+ # EventMachine#open_datagram_socket is for support of UDP-based
819
+ # protocols. Its usage is similar to that of EventMachine#start_server.
820
+ # It takes three parameters: an IP address (which must be valid
821
+ # on the machine which executes the method), a port number,
822
+ # and an optional Module name which will handle the data.
823
+ # This method will create a new UDP (datagram) socket and
824
+ # bind it to the address and port that you specify.
825
+ # The normal callbacks (see EventMachine#start_server) will
826
+ # be called as events of interest occur on the newly-created
827
+ # socket, but there are some differences in how they behave.
828
+ #
829
+ # Connection#receive_data will be called when a datagram packet
830
+ # is received on the socket, but unlike TCP sockets, the message
831
+ # boundaries of the received data will be respected. In other words,
832
+ # if the remote peer sent you a datagram of a particular size,
833
+ # you may rely on Connection#receive_data to give you the
834
+ # exact data in the packet, with the original data length.
835
+ # Also observe that Connection#receive_data may be called with a
836
+ # <i>zero-length</i> data payload, since empty datagrams are permitted
837
+ # in UDP.
838
+ #
839
+ # Connection#send_data is available with UDP packets as with TCP,
840
+ # but there is an important difference. Because UDP communications
841
+ # are <i>connectionless,</i> there is no implicit recipient for the packets you
842
+ # send. Ordinarily you must specify the recipient for each packet you send.
843
+ # However, EventMachine
844
+ # provides for the typical pattern of receiving a UDP datagram
845
+ # from a remote peer, performing some operation, and then sending
846
+ # one or more packets in response to the same remote peer.
847
+ # To support this model easily, just use Connection#send_data
848
+ # in the code that you supply for Connection:receive_data.
849
+ # EventMachine will
850
+ # provide an implicit return address for any messages sent to
851
+ # Connection#send_data within the context of a Connection#receive_data callback,
852
+ # and your response will automatically go to the correct remote peer.
853
+ # (TODO: Example-code needed!)
854
+ #
855
+ # Observe that the port number that you supply to EventMachine#open_datagram_socket
856
+ # may be zero. In this case, EventMachine will create a UDP socket
857
+ # that is bound to an <i>ephemeral</i> (not well-known) port.
858
+ # This is not appropriate for servers that must publish a well-known
859
+ # port to which remote peers may send datagrams. But it can be useful
860
+ # for clients that send datagrams to other servers.
861
+ # If you do this, you will receive any responses from the remote
862
+ # servers through the normal Connection#receive_data callback.
863
+ # Observe that you will probably have issues with firewalls blocking
864
+ # the ephemeral port numbers, so this technique is most appropriate for LANs.
865
+ # (TODO: Need an example!)
866
+ #
867
+ # If you wish to send datagrams to arbitrary remote peers (not
868
+ # necessarily ones that have sent data to which you are responding),
869
+ # then see Connection#send_datagram.
870
+ #
871
+ # DO NOT call send_data from a datagram socket
872
+ # outside of a #receive_data method. Use #send_datagram. If you do use #send_data
873
+ # outside of a #receive_data method, you'll get a confusing error
874
+ # because there is no "peer," as #send_data requires. (Inside of #receive_data,
875
+ # #send_data "fakes" the peer as described above.)
876
+ #
877
+ #--
878
+ # Replaced the implementation on 01Oct06. Thanks to Tobias Gustafsson for pointing
879
+ # out that this originally did not take a class but only a module.
880
+ #
881
+ def self::open_datagram_socket address, port, handler=nil, *args
882
+ klass = if (handler and handler.is_a?(Class))
883
+ handler
884
+ else
885
+ Class.new( Connection ) {handler and include handler}
886
+ end
887
+
888
+ arity = klass.instance_method(:initialize).arity
889
+ expected = arity >= 0 ? arity : -(arity + 1)
890
+ if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
891
+ raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
892
+ end
893
+
894
+ s = open_udp_socket address, port
895
+ c = klass.new s, *args
896
+ @conns[s] = c
897
+ block_given? and yield c
898
+ c
899
+ end
900
+
901
+
902
+ # For advanced users. This function sets the default timer granularity, which by default is
903
+ # slightly smaller than 100 milliseconds. Call this function to set a higher or lower granularity.
904
+ # The function affects the behavior of #add_timer and #add_periodic_timer. Most applications
905
+ # will not need to call this function.
906
+ #
907
+ # The argument is a number of milliseconds. Avoid setting the quantum to very low values because
908
+ # that may reduce performance under some extreme conditions. We recommend that you not set a quantum
909
+ # lower than 10.
910
+ #
911
+ # You may only call this function while an EventMachine loop is running (that is, after a call to
912
+ # EventMachine#run and before a subsequent call to EventMachine#stop).
913
+ #
914
+ def self::set_quantum mills
915
+ set_timer_quantum mills.to_i
916
+ end
917
+
918
+ # Sets the maximum number of timers and periodic timers that may be outstanding at any
919
+ # given time. You only need to call #set_max_timers if you need more than the default
920
+ # number of timers, which on most platforms is 1000.
921
+ # Call this method before calling EventMachine#run.
922
+ #
923
+ def self::set_max_timers ct
924
+ set_max_timer_count ct
925
+ end
926
+
927
+ # Gets the current maximum number of allowed timers
928
+ #
929
+ def self::get_max_timers
930
+ get_max_timer_count
931
+ end
932
+
933
+ #--
934
+ # The is the responder for the loopback-signalled event.
935
+ # It can be fired either by code running on a separate thread (EM#defer) or on
936
+ # the main thread (EM#next_tick).
937
+ # It will often happen that a next_tick handler will reschedule itself. We
938
+ # consume a copy of the tick queue so that tick events scheduled by tick events
939
+ # have to wait for the next pass through the reactor core.
940
+ #
941
+ def self::run_deferred_callbacks # :nodoc:
942
+ until (@resultqueue ||= []).empty?
943
+ result,cback = @resultqueue.pop
944
+ cback.call result if cback
945
+ end
946
+
947
+ @next_tick_queue ||= []
948
+ if (l = @next_tick_queue.length) > 0
949
+ l.times {|i| @next_tick_queue[i].call}
950
+ @next_tick_queue.slice!( 0...l )
951
+ end
952
+
953
+ =begin
954
+ (@next_tick_queue ||= []).length.times {
955
+ cback=@next_tick_queue.pop and cback.call
956
+ }
957
+ =end
958
+ =begin
959
+ if (@next_tick_queue ||= []) and @next_tick_queue.length > 0
960
+ ary = @next_tick_queue.dup
961
+ @next_tick_queue.clear
962
+ until ary.empty?
963
+ cback=ary.pop and cback.call
964
+ end
965
+ end
966
+ =end
967
+ end
968
+
969
+
970
+ # #defer is for integrating blocking operations into EventMachine's control flow.
971
+ # Call #defer with one or two blocks, as shown below (the second block is <i>optional</i>):
972
+ #
973
+ # operation = proc {
974
+ # # perform a long-running operation here, such as a database query.
975
+ # "result" # as usual, the last expression evaluated in the block will be the return value.
976
+ # }
977
+ # callback = proc {|result|
978
+ # # do something with result here, such as send it back to a network client.
979
+ # }
980
+ #
981
+ # EventMachine.defer( operation, callback )
982
+ #
983
+ # The action of #defer is to take the block specified in the first parameter (the "operation")
984
+ # and schedule it for asynchronous execution on an internal thread pool maintained by EventMachine.
985
+ # When the operation completes, it will pass the result computed by the block (if any)
986
+ # back to the EventMachine reactor. Then, EventMachine calls the block specified in the
987
+ # second parameter to #defer (the "callback"), as part of its normal, synchronous
988
+ # event handling loop. The result computed by the operation block is passed as a parameter
989
+ # to the callback. You may omit the callback parameter if you don't need to execute any code
990
+ # after the operation completes.
991
+ #
992
+ # <i>Caveats:</i>
993
+ # Note carefully that the code in your deferred operation will be executed on a separate
994
+ # thread from the main EventMachine processing and all other Ruby threads that may exist in
995
+ # your program. Also, multiple deferred operations may be running at once! Therefore, you
996
+ # are responsible for ensuring that your operation code is threadsafe. [Need more explanation
997
+ # and examples.]
998
+ # Don't write a deferred operation that will block forever. If so, the current implementation will
999
+ # not detect the problem, and the thread will never be returned to the pool. EventMachine limits
1000
+ # the number of threads in its pool, so if you do this enough times, your subsequent deferred
1001
+ # operations won't get a chance to run. [We might put in a timer to detect this problem.]
1002
+ #
1003
+ #--
1004
+ # OBSERVE that #next_tick hacks into this mechanism, so don't make any changes here
1005
+ # without syncing there.
1006
+ #
1007
+ # Running with $VERBOSE set to true gives a warning unless all ivars are defined when
1008
+ # they appear in rvalues. But we DON'T ever want to initialize @threadqueue unless we
1009
+ # need it, because the Ruby threads are so heavyweight. We end up with this bizarre
1010
+ # way of initializing @threadqueue because EventMachine is a Module, not a Class, and
1011
+ # has no constructor.
1012
+ #
1013
+ def self::defer op = nil, callback = nil, &blk
1014
+ unless @threadpool
1015
+ require 'thread'
1016
+ @threadpool = []
1017
+ @threadqueue = Queue.new
1018
+ @resultqueue = Queue.new
1019
+ spawn_threadpool
1020
+ end
1021
+
1022
+ @threadqueue << [op||blk,callback]
1023
+ end
1024
+
1025
+ def self.spawn_threadpool
1026
+ until @threadpool.size == 20
1027
+ thread = Thread.new do
1028
+ while true
1029
+ op, cback = *@threadqueue.pop
1030
+ result = op.call
1031
+ @resultqueue << [result, cback]
1032
+ EventMachine.signal_loopbreak
1033
+ end
1034
+ end
1035
+ @threadpool << thread
1036
+ end
1037
+ end
1038
+
1039
+
1040
+ # Schedules a proc for execution immediately after the next "turn" through the reactor
1041
+ # core. An advanced technique, this can be useful for improving memory management and/or
1042
+ # application responsiveness, especially when scheduling large amounts of data for
1043
+ # writing to a network connection. TODO, we need a FAQ entry on this subject.
1044
+ #
1045
+ # #next_tick takes either a single argument (which must be a Proc) or a block.
1046
+ # And I'm taking suggestions for a better name for this method.
1047
+ #--
1048
+ # This works by adding to the @resultqueue that's used for #defer.
1049
+ # The general idea is that next_tick is used when we want to give the reactor a chance
1050
+ # to let other operations run, either to balance the load out more evenly, or to let
1051
+ # outbound network buffers drain, or both. So we probably do NOT want to block, and
1052
+ # we probably do NOT want to be spinning any threads. A program that uses next_tick
1053
+ # but not #defer shouldn't suffer the penalty of having Ruby threads running. They're
1054
+ # extremely expensive even if they're just sleeping.
1055
+ #
1056
+ def self::next_tick pr=nil, &block
1057
+ raise "no argument or block given" unless ((pr && pr.respond_to?(:call)) or block)
1058
+ (@next_tick_queue ||= []) << ( pr || block )
1059
+ EventMachine.signal_loopbreak
1060
+ =begin
1061
+ (@next_tick_procs ||= []) << (pr || block)
1062
+ if @next_tick_procs.length == 1
1063
+ add_timer(0) {
1064
+ @next_tick_procs.each {|t| t.call}
1065
+ @next_tick_procs.clear
1066
+ }
1067
+ end
1068
+ =end
1069
+ end
1070
+
1071
+ # A wrapper over the setuid system call. Particularly useful when opening a network
1072
+ # server on a privileged port because you can use this call to drop privileges
1073
+ # after opening the port. Also very useful after a call to #set_descriptor_table_size,
1074
+ # which generally requires that you start your process with root privileges.
1075
+ #
1076
+ # This method has no effective implementation on Windows or in the pure-Ruby
1077
+ # implementation of EventMachine.
1078
+ # Call #set_effective_user by passing it a string containing the effective name
1079
+ # of the user whose privilege-level your process should attain.
1080
+ # This method is intended for use in enforcing security requirements, consequently
1081
+ # it will throw a fatal error and end your program if it fails.
1082
+ #
1083
+ def self::set_effective_user username
1084
+ EventMachine::setuid_string username
1085
+ end
1086
+
1087
+
1088
+ # Sets the maximum number of file or socket descriptors that your process may open.
1089
+ # You can pass this method an integer specifying the new size of the descriptor table.
1090
+ # Returns the new descriptor-table size, which may be less than the number you
1091
+ # requested. If you call this method with no arguments, it will simply return
1092
+ # the current size of the descriptor table without attempting to change it.
1093
+ #
1094
+ # The new limit on open descriptors ONLY applies to sockets and other descriptors
1095
+ # that belong to EventMachine. It has NO EFFECT on the number of descriptors
1096
+ # you can create in ordinary Ruby code.
1097
+ #
1098
+ # Not available on all platforms. Increasing the number of descriptors beyond its
1099
+ # default limit usually requires superuser privileges. (See #set_effective_user
1100
+ # for a way to drop superuser privileges while your program is running.)
1101
+ #
1102
+ def self::set_descriptor_table_size n_descriptors=nil
1103
+ EventMachine::set_rlimit_nofile n_descriptors
1104
+ end
1105
+
1106
+
1107
+
1108
+ # TODO, must document popen. At this moment, it's only available on Unix.
1109
+ # This limitation is expected to go away.
1110
+ #--
1111
+ # Perhaps misnamed since the underlying function uses socketpair and is full-duplex.
1112
+ #
1113
+ def self::popen cmd, handler=nil, *args
1114
+ klass = if (handler and handler.is_a?(Class))
1115
+ handler
1116
+ else
1117
+ Class.new( Connection ) {handler and include handler}
1118
+ end
1119
+
1120
+ w = Shellwords::shellwords( cmd )
1121
+ w.unshift( w.first ) if w.first
1122
+ s = invoke_popen( w )
1123
+ c = klass.new s, *args
1124
+ @conns[s] = c
1125
+ yield(c) if block_given?
1126
+ c
1127
+ end
1128
+
1129
+
1130
+ # Tells you whether the EventMachine reactor loop is currently running. Returns true or
1131
+ # false. Useful when writing libraries that want to run event-driven code, but may
1132
+ # be running in programs that are already event-driven. In such cases, if EventMachine#reactor_running?
1133
+ # returns false, your code can invoke EventMachine#run and run your application code inside
1134
+ # the block passed to that method. If EventMachine#reactor_running? returns true, just
1135
+ # execute your event-aware code.
1136
+ #
1137
+ # This method is necessary because calling EventMachine#run inside of another call to
1138
+ # EventMachine#run generates a fatal error.
1139
+ #
1140
+ def self::reactor_running?
1141
+ (@reactor_running || false)
1142
+ end
1143
+
1144
+
1145
+ # (Experimental)
1146
+ #
1147
+ #
1148
+ def EventMachine::open_keyboard handler=nil, *args
1149
+ klass = if (handler and handler.is_a?(Class))
1150
+ handler
1151
+ else
1152
+ Class.new( Connection ) {handler and include handler}
1153
+ end
1154
+
1155
+ arity = klass.instance_method(:initialize).arity
1156
+ expected = arity >= 0 ? arity : -(arity + 1)
1157
+ if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
1158
+ raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
1159
+ end
1160
+
1161
+ s = read_keyboard
1162
+ c = klass.new s, *args
1163
+ @conns[s] = c
1164
+ block_given? and yield c
1165
+ c
1166
+ end
1167
+
1168
+
1169
+
1170
+ private
1171
+ def EventMachine::event_callback conn_binding, opcode, data
1172
+ #
1173
+ # Changed 27Dec07: Eliminated the hookable error handling.
1174
+ # No one was using it, and it degraded performance significantly.
1175
+ # It's in original_event_callback, which is dead code.
1176
+ #
1177
+ # Changed 25Jul08: Added a partial solution to the problem of exceptions
1178
+ # raised in user-written event-handlers. If such exceptions are not caught,
1179
+ # we must cause the reactor to stop, and then re-raise the exception.
1180
+ # Otherwise, the reactor doesn't stop and it's left on the call stack.
1181
+ # This is partial because we only added it to #unbind, where it's critical
1182
+ # (to keep unbind handlers from being re-entered when a stopping reactor
1183
+ # runs down open connections). It should go on the other calls to user
1184
+ # code, but the performance impact may be too large.
1185
+ #
1186
+ if opcode == ConnectionData
1187
+ c = @conns[conn_binding] or raise ConnectionNotBound, "received data #{data} for unknown signature: #{conn_binding}"
1188
+ c.receive_data data
1189
+ elsif opcode == ConnectionUnbound
1190
+ if c = @conns.delete( conn_binding )
1191
+ begin
1192
+ c.unbind
1193
+ rescue
1194
+ @wrapped_exception = $!
1195
+ stop
1196
+ end
1197
+ elsif c = @acceptors.delete( conn_binding )
1198
+ # no-op
1199
+ else
1200
+ raise ConnectionNotBound, "recieved ConnectionUnbound for an unknown signature: #{conn_binding}"
1201
+ end
1202
+ elsif opcode == ConnectionAccepted
1203
+ accep,args,blk = @acceptors[conn_binding]
1204
+ raise NoHandlerForAcceptedConnection unless accep
1205
+ c = accep.new data, *args
1206
+ @conns[data] = c
1207
+ blk and blk.call(c)
1208
+ c # (needed?)
1209
+ elsif opcode == TimerFired
1210
+ t = @timers.delete( data ) or raise UnknownTimerFired, "timer data: #{data}"
1211
+ t.call
1212
+ elsif opcode == ConnectionCompleted
1213
+ c = @conns[conn_binding] or raise ConnectionNotBound, "received ConnectionCompleted for unknown signature: #{conn_binding}"
1214
+ c.connection_completed
1215
+ elsif opcode == LoopbreakSignalled
1216
+ run_deferred_callbacks
1217
+ elsif opcode == ConnectionNotifyReadable
1218
+ c = @conns[conn_binding] or raise ConnectionNotBound
1219
+ c.notify_readable
1220
+ elsif opcode == ConnectionNotifyWritable
1221
+ c = @conns[conn_binding] or raise ConnectionNotBound
1222
+ c.notify_writable
1223
+ end
1224
+ end
1225
+
1226
+ private
1227
+ def EventMachine::original_event_callback conn_binding, opcode, data
1228
+ #
1229
+ # Added 03Oct07: Any code path that invokes user-written code must
1230
+ # wrap itself in a begin/rescue for RuntimeErrors, that calls the
1231
+ # user-overridable class method #handle_runtime_error.
1232
+ #
1233
+ if opcode == ConnectionData
1234
+ c = @conns[conn_binding] or raise ConnectionNotBound
1235
+ begin
1236
+ c.receive_data data
1237
+ rescue
1238
+ EventMachine.handle_runtime_error
1239
+ end
1240
+ elsif opcode == ConnectionUnbound
1241
+ if c = @conns.delete( conn_binding )
1242
+ begin
1243
+ c.unbind
1244
+ rescue
1245
+ EventMachine.handle_runtime_error
1246
+ end
1247
+ elsif c = @acceptors.delete( conn_binding )
1248
+ # no-op
1249
+ else
1250
+ raise ConnectionNotBound
1251
+ end
1252
+ elsif opcode == ConnectionAccepted
1253
+ accep,args,blk = @acceptors[conn_binding]
1254
+ raise NoHandlerForAcceptedConnection unless accep
1255
+ c = accep.new data, *args
1256
+ @conns[data] = c
1257
+ begin
1258
+ blk and blk.call(c)
1259
+ rescue
1260
+ EventMachine.handle_runtime_error
1261
+ end
1262
+ c # (needed?)
1263
+ elsif opcode == TimerFired
1264
+ t = @timers.delete( data ) or raise UnknownTimerFired
1265
+ begin
1266
+ t.call
1267
+ rescue
1268
+ EventMachine.handle_runtime_error
1269
+ end
1270
+ elsif opcode == ConnectionCompleted
1271
+ c = @conns[conn_binding] or raise ConnectionNotBound
1272
+ begin
1273
+ c.connection_completed
1274
+ rescue
1275
+ EventMachine.handle_runtime_error
1276
+ end
1277
+ elsif opcode == LoopbreakSignalled
1278
+ begin
1279
+ run_deferred_callbacks
1280
+ rescue
1281
+ EventMachine.handle_runtime_error
1282
+ end
1283
+ end
1284
+ end
1285
+
1286
+
1287
+ # Default handler for RuntimeErrors that are raised in user code.
1288
+ # The default behavior is to re-raise the error, which ends your program.
1289
+ # To override the default behavior, re-implement this method in your code.
1290
+ # For example:
1291
+ #
1292
+ # module EventMachine
1293
+ # def self.handle_runtime_error
1294
+ # $>.puts $!
1295
+ # end
1296
+ # end
1297
+ #
1298
+ #--
1299
+ # We need to ensure that any code path which invokes user code rescues RuntimeError
1300
+ # and calls this method. The obvious place to do that is in #event_callback,
1301
+ # but, scurrilously, it turns out that we need to be finer grained that that.
1302
+ # Periodic timers, in particular, wrap their invocations of user code inside
1303
+ # procs that do other stuff we can't not do, like schedule the next invocation.
1304
+ # This is a potential non-robustness, since we need to remember to hook in the
1305
+ # error handler whenever and wherever we change how user code is invoked.
1306
+ #
1307
+ def EventMachine::handle_runtime_error
1308
+ @runtime_error_hook ? @runtime_error_hook.call : raise
1309
+ end
1310
+
1311
+ # Sets a handler for RuntimeErrors that are raised in user code.
1312
+ # Pass a block with no parameters. You can also call this method without a block,
1313
+ # which restores the default behavior (see #handle_runtime_error).
1314
+ #
1315
+ def EventMachine::set_runtime_error_hook &blk
1316
+ @runtime_error_hook = blk
1317
+ end
1318
+
1319
+ # Documentation stub
1320
+ #--
1321
+ # This is a provisional implementation of a stream-oriented file access object.
1322
+ # We also experiment with wrapping up some better exception reporting.
1323
+ class << self
1324
+ def _open_file_for_writing filename, handler=nil
1325
+ klass = if (handler and handler.is_a?(Class))
1326
+ handler
1327
+ else
1328
+ Class.new( Connection ) {handler and include handler}
1329
+ end
1330
+
1331
+ s = _write_file filename
1332
+ c = klass.new s
1333
+ @conns[s] = c
1334
+ block_given? and yield c
1335
+ c
1336
+ end
1337
+ end
1338
+
1339
+
1340
+ # EventMachine::Connection is a class that is instantiated
1341
+ # by EventMachine's processing loop whenever a new connection
1342
+ # is created. (New connections can be either initiated locally
1343
+ # to a remote server or accepted locally from a remote client.)
1344
+ # When a Connection object is instantiated, it <i>mixes in</i>
1345
+ # the functionality contained in the user-defined module
1346
+ # specified in calls to EventMachine#connect or EventMachine#start_server.
1347
+ # User-defined handler modules may redefine any or all of the standard
1348
+ # methods defined here, as well as add arbitrary additional code
1349
+ # that will also be mixed in.
1350
+ #
1351
+ # EventMachine manages one object inherited from EventMachine::Connection
1352
+ # (and containing the mixed-in user code) for every network connection
1353
+ # that is active at any given time.
1354
+ # The event loop will automatically call methods on EventMachine::Connection
1355
+ # objects whenever specific events occur on the corresponding connections,
1356
+ # as described below.
1357
+ #
1358
+ # This class is never instantiated by user code, and does not publish an
1359
+ # initialize method. The instance methods of EventMachine::Connection
1360
+ # which may be called by the event loop are: post_init, receive_data,
1361
+ # and unbind. All of the other instance methods defined here are called
1362
+ # only by user code.
1363
+ #
1364
+ class Connection
1365
+ # EXPERIMENTAL. Added the reconnect methods, which may go away.
1366
+ attr_accessor :signature
1367
+
1368
+ # Override .new so subclasses don't have to call super and can ignore
1369
+ # connection-specific arguments
1370
+ #
1371
+ def self.new(sig, *args) #:nodoc:
1372
+ allocate.instance_eval do
1373
+ # Call a superclass's #initialize if it has one
1374
+ initialize(*args)
1375
+
1376
+ # Store signature and run #post_init
1377
+ @signature = sig
1378
+ associate_callback_target sig
1379
+ post_init
1380
+
1381
+ self
1382
+ end
1383
+ end
1384
+
1385
+ # Stubbed initialize so legacy superclasses can safely call super
1386
+ #
1387
+ def initialize(*args) #:nodoc:
1388
+ end
1389
+
1390
+ def associate_callback_target(sig) #:nodoc:
1391
+ # no-op for the time being, to match similar no-op in rubymain.cpp
1392
+ end
1393
+
1394
+ # EventMachine::Connection#post_init is called by the event loop
1395
+ # immediately after the network connection has been established,
1396
+ # and before resumption of the network loop.
1397
+ # This method is generally not called by user code, but is called automatically
1398
+ # by the event loop. The base-class implementation is a no-op.
1399
+ # This is a very good place to initialize instance variables that will
1400
+ # be used throughout the lifetime of the network connection.
1401
+ #
1402
+ def post_init
1403
+ end
1404
+
1405
+ # EventMachine::Connection#receive_data is called by the event loop
1406
+ # whenever data has been received by the network connection.
1407
+ # It is never called by user code.
1408
+ # receive_data is called with a single parameter, a String containing
1409
+ # the network protocol data, which may of course be binary. You will
1410
+ # generally redefine this method to perform your own processing of the incoming data.
1411
+ #
1412
+ # Here's a key point which is essential to understanding the event-driven
1413
+ # programming model: <i>EventMachine knows absolutely nothing about the protocol
1414
+ # which your code implements.</i> You must not make any assumptions about
1415
+ # the size of the incoming data packets, or about their alignment on any
1416
+ # particular intra-message or PDU boundaries (such as line breaks).
1417
+ # receive_data can and will send you arbitrary chunks of data, with the
1418
+ # only guarantee being that the data is presented to your code in the order
1419
+ # it was collected from the network. Don't even assume that the chunks of
1420
+ # data will correspond to network packets, as EventMachine can and will coalesce
1421
+ # several incoming packets into one, to improve performance. The implication for your
1422
+ # code is that you generally will need to implement some kind of a state machine
1423
+ # in your redefined implementation of receive_data. For a better understanding
1424
+ # of this, read through the examples of specific protocol handlers given
1425
+ # elsewhere in this package. (STUB, WE MUST ADD THESE!)
1426
+ #
1427
+ # The base-class implementation of receive_data (which will be invoked if
1428
+ # you don't redefine it) simply prints the size of each incoming data packet
1429
+ # to stdout.
1430
+ #
1431
+ def receive_data data
1432
+ puts "............>>>#{data.length}"
1433
+ end
1434
+
1435
+ # #ssl_handshake_completed is called by EventMachine when the SSL/TLS handshake has
1436
+ # been completed, as a result of calling #start_tls to initiate SSL/TLS on the connection.
1437
+ #
1438
+ # This callback exists because #post_init and #connection_completed are <b>not</b> reliable
1439
+ # for indicating when an SSL/TLS connection is ready to have it's certificate queried for.
1440
+ #
1441
+ # See #get_peer_cert for application and example.
1442
+ def ssl_handshake_completed
1443
+ end
1444
+
1445
+ # EventMachine::Connection#unbind is called by the framework whenever a connection
1446
+ # (either a server or client connection) is closed. The close can occur because
1447
+ # your code intentionally closes it (see close_connection and close_connection_after_writing),
1448
+ # because the remote peer closed the connection, or because of a network error.
1449
+ # You may not assume that the network connection is still open and able to send or
1450
+ # receive data when the callback to unbind is made. This is intended only to give
1451
+ # you a chance to clean up associations your code may have made to the connection
1452
+ # object while it was open.
1453
+ #
1454
+ def unbind
1455
+ end
1456
+
1457
+ # EventMachine::Connection#close_connection is called only by user code, and never
1458
+ # by the event loop. You may call this method against a connection object in any
1459
+ # callback handler, whether or not the callback was made against the connection
1460
+ # you want to close. close_connection <i>schedules</i> the connection to be closed
1461
+ # at the next available opportunity within the event loop. You may not assume that
1462
+ # the connection is closed when close_connection returns. In particular, the framework
1463
+ # will callback the unbind method for the particular connection at a point shortly
1464
+ # after you call close_connection. You may assume that the unbind callback will
1465
+ # take place sometime after your call to close_connection completes. In other words,
1466
+ # the unbind callback will not re-enter your code "inside" of your call to close_connection.
1467
+ # However, it's not guaranteed that a future version of EventMachine will not change
1468
+ # this behavior.
1469
+ #
1470
+ # close_connection will <i>silently discard</i> any outbound data which you have
1471
+ # sent to the connection using EventMachine::Connection#send_data but which has not
1472
+ # yet been sent across the network. If you want to avoid this behavior, use
1473
+ # EventMachine::Connection#close_connection_after_writing.
1474
+ #
1475
+ def close_connection after_writing = false
1476
+ EventMachine::close_connection @signature, after_writing
1477
+ end
1478
+
1479
+ # EventMachine::Connection#detach will remove the given connection from the event loop.
1480
+ # The connection's socket remains open and its file descriptor number is returned
1481
+ def detach
1482
+ EventMachine::detach_fd @signature
1483
+ end
1484
+
1485
+ # EventMachine::Connection#close_connection_after_writing is a variant of close_connection.
1486
+ # All of the descriptive comments given for close_connection also apply to
1487
+ # close_connection_after_writing, <i>with one exception:</i> If the connection has
1488
+ # outbound data sent using send_dat but which has not yet been sent across the network,
1489
+ # close_connection_after_writing will schedule the connection to be closed <i>after</i>
1490
+ # all of the outbound data has been safely written to the remote peer.
1491
+ #
1492
+ # Depending on the amount of outgoing data and the speed of the network,
1493
+ # considerable time may elapse between your call to close_connection_after_writing
1494
+ # and the actual closing of the socket (at which time the unbind callback will be called
1495
+ # by the event loop). During this time, you <i>may not</i> call send_data to transmit
1496
+ # additional data (that is, the connection is closed for further writes). In very
1497
+ # rare cases, you may experience a receive_data callback after your call to close_connection_after_writing,
1498
+ # depending on whether incoming data was in the process of being received on the connection
1499
+ # at the moment when you called close_connection_after_writing. Your protocol handler must
1500
+ # be prepared to properly deal with such data (probably by ignoring it).
1501
+ #
1502
+ def close_connection_after_writing
1503
+ close_connection true
1504
+ end
1505
+
1506
+ # EventMachine::Connection#send_data is only called by user code, never by
1507
+ # the event loop. You call this method to send data to the remote end of the
1508
+ # network connection. send_data is called with a single String argument, which
1509
+ # may of course contain binary data. You can call send_data any number of times.
1510
+ # send_data is an instance method of an object derived from EventMachine::Connection
1511
+ # and containing your mixed-in handler code), so if you call it without qualification
1512
+ # within a callback function, the data will be sent to the same network connection
1513
+ # that generated the callback. Calling self.send_data is exactly equivalent.
1514
+ #
1515
+ # You can also call send_data to write to a connection <i>other than the one
1516
+ # whose callback you are calling send_data from.</i> This is done by recording
1517
+ # the value of the connection in any callback function (the value self), in any
1518
+ # variable visible to other callback invocations on the same or different
1519
+ # connection objects. (Need an example to make that clear.)
1520
+ #
1521
+ def send_data data
1522
+ size = data.bytesize if data.respond_to?(:bytesize)
1523
+ size ||= data.size
1524
+ EventMachine::send_data @signature, data, size
1525
+ end
1526
+
1527
+ # Returns true if the connection is in an error state, false otherwise.
1528
+ # In general, you can detect the occurrence of communication errors or unexpected
1529
+ # disconnection by the remote peer by handing the #unbind method. In some cases, however,
1530
+ # it's useful to check the status of the connection using #error? before attempting to send data.
1531
+ # This function is synchronous: it will return immediately without blocking.
1532
+ #
1533
+ #
1534
+ def error?
1535
+ EventMachine::report_connection_error_status(@signature) != 0
1536
+ end
1537
+
1538
+ # #connection_completed is called by the event loop when a remote TCP connection
1539
+ # attempt completes successfully. You can expect to get this notification after calls
1540
+ # to EventMachine#connect. Remember that EventMachine makes remote connections
1541
+ # asynchronously, just as with any other kind of network event. #connection_completed
1542
+ # is intended primarily to assist with network diagnostics. For normal protocol
1543
+ # handling, use #post_init to perform initial work on a new connection (such as
1544
+ # send an initial set of data).
1545
+ # #post_init will always be called. #connection_completed will only be called in case
1546
+ # of a successful completion. A connection-attempt which fails will receive a call
1547
+ # to #unbind after the failure.
1548
+ def connection_completed
1549
+ end
1550
+
1551
+ # Call #start_tls at any point to initiate TLS encryption on connected streams.
1552
+ # The method is smart enough to know whether it should perform a server-side
1553
+ # or a client-side handshake. An appropriate place to call #start_tls is in
1554
+ # your redefined #post_init method, or in the #connection_completed handler for
1555
+ # an outbound connection.
1556
+ #
1557
+ # #start_tls takes an optional parameter hash that allows you to specify certificate
1558
+ # and other options to be used with this Connection object. Here are the currently-supported
1559
+ # options:
1560
+ # :cert_chain_file : takes a String, which is interpreted as the name of a readable file in the
1561
+ # local filesystem. The file is expected to contain a chain of X509 certificates in
1562
+ # PEM format, with the most-resolved certificate at the top of the file, successive
1563
+ # intermediate certs in the middle, and the root (or CA) cert at the bottom.
1564
+ #
1565
+ # :private_key_file : tales a String, which is interpreted as the name of a readable file in the
1566
+ # local filesystem. The file must contain a private key in PEM format.
1567
+ #
1568
+ #--
1569
+ # TODO: support passing an encryption parameter, which can be string or Proc, to get a passphrase
1570
+ # for encrypted private keys.
1571
+ # TODO: support passing key material via raw strings or Procs that return strings instead of
1572
+ # just filenames.
1573
+ # What will get nasty is whether we have to define a location for storing this stuff as files.
1574
+ # In general, the OpenSSL interfaces for dealing with certs and keys in files are much better
1575
+ # behaved than the ones for raw chunks of memory.
1576
+ #
1577
+ def start_tls args={}
1578
+ priv_key, cert_chain = args.values_at(:private_key_file, :cert_chain_file)
1579
+
1580
+ [priv_key, cert_chain].each do |file|
1581
+ next if file.nil? or file.empty?
1582
+ raise FileNotFoundException,
1583
+ "Could not find #{file} for start_tls" unless File.exists? file
1584
+ end
1585
+
1586
+ EventMachine::set_tls_parms(@signature, priv_key || '', cert_chain || '')
1587
+
1588
+ EventMachine::start_tls @signature
1589
+ end
1590
+
1591
+ # If SSL/TLS is active on the connection, #get_peer_cert returns the remote X509 certificate
1592
+ # as a String, in the popular PEM format. This can then be used for arbitrary validation
1593
+ # of a peer's certificate in your code.
1594
+ #
1595
+ # This should be called in/after the #ssl_handshake_completed callback, which indicates
1596
+ # that SSL/TLS is active. Using this callback is important, because the certificate may not
1597
+ # be available until the time it is executed. Using #post_init or #connection_completed is
1598
+ # not adequate, because the SSL handshake may still be taking place.
1599
+ #
1600
+ # #get_peer_cert will return <b>nil</b> if:
1601
+ #
1602
+ # * EventMachine is not built with OpenSSL support
1603
+ # * SSL/TLS is not active on the connection
1604
+ # * SSL/TLS handshake is not yet complete
1605
+ # * Remote peer for any other reason has not presented a certificate
1606
+ #
1607
+ # === Example:
1608
+ #
1609
+ # module Handler
1610
+ #
1611
+ # def post_init
1612
+ # puts "Starting TLS"
1613
+ # start_tls
1614
+ # end
1615
+ #
1616
+ # def ssl_handshake_completed
1617
+ # puts get_peer_cert
1618
+ # close_connection
1619
+ # end
1620
+ #
1621
+ # def unbind
1622
+ # EventMachine::stop_event_loop
1623
+ # end
1624
+ #
1625
+ # end
1626
+ #
1627
+ # EM.run {
1628
+ # EventMachine::connect "mail.google.com", 443, Handler
1629
+ # }
1630
+ #
1631
+ # Output:
1632
+ # -----BEGIN CERTIFICATE-----
1633
+ # MIIDIjCCAougAwIBAgIQbldpChBPqv+BdPg4iwgN8TANBgkqhkiG9w0BAQUFADBM
1634
+ # MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
1635
+ # THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wODA1MDIxNjMyNTRaFw0w
1636
+ # OTA1MDIxNjMyNTRaMGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
1637
+ # MRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRgw
1638
+ # FgYDVQQDEw9tYWlsLmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
1639
+ # AoGBALlkxdh2QXegdElukCSOV2+8PKiONIS+8Tu9K7MQsYpqtLNC860zwOPQ2NLI
1640
+ # 3Zp4jwuXVTrtzGuiqf5Jioh35Ig3CqDXtLyZoypjZUQcq4mlLzHlhIQ4EhSjDmA7
1641
+ # Ffw9y3ckSOQgdBQWNLbquHh9AbEUjmhkrYxIqKXeCnRKhv6nAgMBAAGjgecwgeQw
1642
+ # KAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUFBwMCBglghkgBhvhCBAEwNgYDVR0f
1643
+ # BC8wLTAroCmgJ4YlaHR0cDovL2NybC50aGF3dGUuY29tL1RoYXd0ZVNHQ0NBLmNy
1644
+ # bDByBggrBgEFBQcBAQRmMGQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnRoYXd0
1645
+ # ZS5jb20wPgYIKwYBBQUHMAKGMmh0dHA6Ly93d3cudGhhd3RlLmNvbS9yZXBvc2l0
1646
+ # b3J5L1RoYXd0ZV9TR0NfQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEF
1647
+ # BQADgYEAsRwpLg1dgCR1gYDK185MFGukXMeQFUvhGqF8eT/CjpdvezyKVuz84gSu
1648
+ # 6ccMXgcPQZGQN/F4Xug+Q01eccJjRSVfdvR5qwpqCj+6BFl5oiKDBsveSkrmL5dz
1649
+ # s2bn7TdTSYKcLeBkjXxDLHGBqLJ6TNCJ3c4/cbbG5JhGvoema94=
1650
+ # -----END CERTIFICATE-----
1651
+ #
1652
+ # You can do whatever you want with the certificate String, such as load it
1653
+ # as a certificate object using the OpenSSL library, and check it's fields.
1654
+ def get_peer_cert
1655
+ EventMachine::get_peer_cert @signature
1656
+ end
1657
+
1658
+
1659
+ # send_datagram is for sending UDP messages.
1660
+ # This method may be called from any Connection object that refers
1661
+ # to an open datagram socket (see EventMachine#open_datagram_socket).
1662
+ # The method sends a UDP (datagram) packet containing the data you specify,
1663
+ # to a remote peer specified by the IP address and port that you give
1664
+ # as parameters to the method.
1665
+ # Observe that you may send a zero-length packet (empty string).
1666
+ # However, you may not send an arbitrarily-large data packet because
1667
+ # your operating system will enforce a platform-specific limit on
1668
+ # the size of the outbound packet. (Your kernel
1669
+ # will respond in a platform-specific way if you send an overlarge
1670
+ # packet: some will send a truncated packet, some will complain, and
1671
+ # some will silently drop your request).
1672
+ # On LANs, it's usually OK to send datagrams up to about 4000 bytes in length,
1673
+ # but to be really safe, send messages smaller than the Ethernet-packet
1674
+ # size (typically about 1400 bytes). Some very restrictive WANs
1675
+ # will either drop or truncate packets larger than about 500 bytes.
1676
+ #--
1677
+ # Added the Integer wrapper around the port parameter per suggestion by
1678
+ # Matthieu Riou, after he passed a String and spent hours tearing his hair out.
1679
+ #
1680
+ def send_datagram data, recipient_address, recipient_port
1681
+ data = data.to_s
1682
+ EventMachine::send_datagram @signature, data, data.length, recipient_address, Integer(recipient_port)
1683
+ end
1684
+
1685
+
1686
+ # #get_peername is used with stream-connections to obtain the identity
1687
+ # of the remotely-connected peer. If a peername is available, this method
1688
+ # returns a sockaddr structure. The method returns nil if no peername is available.
1689
+ # You can use Socket#unpack_sockaddr_in and its variants to obtain the
1690
+ # values contained in the peername structure returned from #get_peername.
1691
+ def get_peername
1692
+ EventMachine::get_peername @signature
1693
+ end
1694
+
1695
+ # #get_sockname is used with stream-connections to obtain the identity
1696
+ # of the local side of the connection. If a local name is available, this method
1697
+ # returns a sockaddr structure. The method returns nil if no local name is available.
1698
+ # You can use Socket#unpack_sockaddr_in and its variants to obtain the
1699
+ # values contained in the local-name structure returned from #get_sockname.
1700
+ def get_sockname
1701
+ EventMachine::get_sockname @signature
1702
+ end
1703
+
1704
+ # Returns the PID (kernel process identifier) of a subprocess
1705
+ # associated with this Connection object. For use with EventMachine#popen
1706
+ # and similar methods. Returns nil when there is no meaningful subprocess.
1707
+ #--
1708
+ #
1709
+ def get_pid
1710
+ EventMachine::get_subprocess_pid @signature
1711
+ end
1712
+
1713
+ # Returns a subprocess exit status. Only useful for #popen. Call it in your
1714
+ # #unbind handler.
1715
+ #
1716
+ def get_status
1717
+ EventMachine::get_subprocess_status @signature
1718
+ end
1719
+
1720
+ # comm_inactivity_timeout returns the current value (in seconds) of the inactivity-timeout
1721
+ # property of network-connection and datagram-socket objects. A nonzero value
1722
+ # indicates that the connection or socket will automatically be closed if no read or write
1723
+ # activity takes place for at least that number of seconds.
1724
+ # A zero value (the default) specifies that no automatic timeout will take place.
1725
+ def comm_inactivity_timeout
1726
+ EventMachine::get_comm_inactivity_timeout @signature
1727
+ end
1728
+
1729
+ # Alias for #set_comm_inactivity_timeout.
1730
+ def comm_inactivity_timeout= value
1731
+ self.send :set_comm_inactivity_timeout, value
1732
+ end
1733
+
1734
+ # comm_inactivity_timeout= allows you to set the inactivity-timeout property for
1735
+ # a network connection or datagram socket. Specify a non-negative numeric value in seconds.
1736
+ # If the value is greater than zero, the connection or socket will automatically be closed
1737
+ # if no read or write activity takes place for at least that number of seconds.
1738
+ # Specify a value of zero to indicate that no automatic timeout should take place.
1739
+ # Zero is the default value.
1740
+ def set_comm_inactivity_timeout value
1741
+ EventMachine::set_comm_inactivity_timeout @signature, value
1742
+ end
1743
+
1744
+ #--
1745
+ # EXPERIMENTAL. DO NOT RELY ON THIS METHOD TO REMAIN SUPPORTED.
1746
+ # (03Nov06)
1747
+ def reconnect server, port
1748
+ EventMachine::reconnect server, port, self
1749
+ end
1750
+
1751
+
1752
+ # Like EventMachine::Connection#send_data, this sends data to the remote end of
1753
+ # the network connection. EventMachine::Connection@send_file_data takes a
1754
+ # filename as an argument, though, and sends the contents of the file, in one
1755
+ # chunk. Contributed by Kirk Haines.
1756
+ #
1757
+ def send_file_data filename
1758
+ EventMachine::send_file_data @signature, filename
1759
+ end
1760
+
1761
+ # Open a file on the filesystem and send it to the remote peer. This returns an
1762
+ # object of type EventMachine::Deferrable. The object's callbacks will be executed
1763
+ # on the reactor main thread when the file has been completely scheduled for
1764
+ # transmission to the remote peer. Its errbacks will be called in case of an error
1765
+ # (such as file-not-found). #stream_file_data employs various strategems to achieve
1766
+ # the fastest possible performance, balanced against minimum consumption of memory.
1767
+ #
1768
+ # You can control the behavior of #stream_file_data with the optional arguments parameter.
1769
+ # Currently-supported arguments are:
1770
+ # :http_chunks, a boolean flag which defaults false. If true, this flag streams the
1771
+ # file data in a format compatible with the HTTP chunked-transfer encoding.
1772
+ #
1773
+ # Warning: this feature has an implicit dependency on an outboard extension,
1774
+ # evma_fastfilereader. You must install this extension in order to use #stream_file_data
1775
+ # with files larger than a certain size (currently 8192 bytes).
1776
+ #
1777
+ def stream_file_data filename, args={}
1778
+ EventMachine::FileStreamer.new( self, filename, args )
1779
+ end
1780
+
1781
+
1782
+ # TODO, document this
1783
+ #
1784
+ #
1785
+ class EventMachine::PeriodicTimer
1786
+ attr_accessor :interval
1787
+ def initialize *args, &block
1788
+ @interval = args.shift
1789
+ @code = args.shift || block
1790
+ schedule
1791
+ end
1792
+ def schedule
1793
+ EventMachine::add_timer @interval, proc {self.fire}
1794
+ end
1795
+ def fire
1796
+ unless @cancelled
1797
+ @code.call
1798
+ schedule
1799
+ end
1800
+ end
1801
+ def cancel
1802
+ @cancelled = true
1803
+ end
1804
+ end
1805
+
1806
+ # TODO, document this
1807
+ #
1808
+ #
1809
+ class EventMachine::Timer
1810
+ def initialize *args, &block
1811
+ @signature = EventMachine::add_timer(*args, &block)
1812
+ end
1813
+ def cancel
1814
+ EventMachine.send :cancel_timer, @signature
1815
+ end
1816
+ end
1817
+
1818
+ end
1819
+
1820
+ # Is inside of protocols/ but not in the namespace?
1821
+ require 'protocols/buftok'
1822
+
1823
+ module Protocols
1824
+ # In this module, we define standard protocol implementations.
1825
+ # They get included from separate source files.
1826
+
1827
+ # TODO / XXX: We're munging the LOAD_PATH!
1828
+ # A good citizen would use eventmachine/protocols/tcptest.
1829
+ # TODO : various autotools are completely useless with the lack of naming
1830
+ # convention, we need to correct that!
1831
+ autoload :TcpConnectTester, 'protocols/tcptest'
1832
+ autoload :HttpClient, 'protocols/httpclient'
1833
+ autoload :LineAndTextProtocol, 'protocols/line_and_text'
1834
+ autoload :HeaderAndContentProtocol, 'protocols/header_and_content'
1835
+ autoload :LineText2, 'protocols/linetext2'
1836
+ autoload :HttpClient2, 'protocols/httpcli2'
1837
+ autoload :Stomp, 'protocols/stomp'
1838
+ autoload :SmtpClient, 'protocols/smtpclient'
1839
+ autoload :SmtpServer, 'protocols/smtpserver'
1840
+ autoload :SASLauth, 'protocols/saslauth'
1841
+ autoload :Memcache, 'protocols/memcache'
1842
+
1843
+ #require 'protocols/postgres' UNCOMMENT THIS LINE WHEN THE POSTGRES CODE IS READY FOR PRIME TIME.
1844
+ end
1845
+
1846
+ end # module EventMachine
1847
+
1848
+ # Save everyone some typing.
1849
+ EM = EventMachine
1850
+ EM::P = EventMachine::Protocols
1851
+
1852
+ require 'em/processes'