eventmachine 0.12.6-java

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