eventmachine 0.12.10-x86-mswin32-60 → 1.0.0.beta.2-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +1 -0
  3. data/README +80 -81
  4. data/Rakefile +7 -370
  5. data/docs/COPYING +60 -60
  6. data/docs/ChangeLog +211 -211
  7. data/docs/DEFERRABLES +246 -133
  8. data/docs/EPOLL +141 -141
  9. data/docs/GNU +281 -281
  10. data/docs/INSTALL +13 -13
  11. data/docs/KEYBOARD +42 -38
  12. data/docs/LEGAL +25 -25
  13. data/docs/LIGHTWEIGHT_CONCURRENCY +130 -70
  14. data/docs/PURE_RUBY +75 -75
  15. data/docs/RELEASE_NOTES +94 -94
  16. data/docs/SMTP +4 -2
  17. data/docs/SPAWNED_PROCESSES +148 -89
  18. data/docs/TODO +8 -8
  19. data/eventmachine.gemspec +19 -26
  20. data/examples/ex_channel.rb +42 -42
  21. data/examples/ex_queue.rb +2 -2
  22. data/examples/ex_tick_loop_array.rb +15 -0
  23. data/examples/ex_tick_loop_counter.rb +32 -0
  24. data/examples/helper.rb +1 -1
  25. data/ext/binder.cpp +0 -1
  26. data/ext/cmain.cpp +36 -25
  27. data/ext/ed.cpp +104 -113
  28. data/ext/ed.h +24 -30
  29. data/ext/em.cpp +349 -283
  30. data/ext/em.h +25 -29
  31. data/ext/eventmachine.h +5 -4
  32. data/ext/extconf.rb +58 -49
  33. data/ext/fastfilereader/extconf.rb +5 -3
  34. data/ext/fastfilereader/mapper.cpp +214 -214
  35. data/ext/fastfilereader/mapper.h +59 -59
  36. data/ext/fastfilereader/rubymain.cpp +127 -127
  37. data/ext/kb.cpp +1 -3
  38. data/ext/page.cpp +107 -107
  39. data/ext/page.h +51 -51
  40. data/ext/pipe.cpp +9 -11
  41. data/ext/project.h +12 -8
  42. data/ext/rubymain.cpp +138 -104
  43. data/java/.classpath +8 -8
  44. data/java/.project +17 -17
  45. data/java/src/com/rubyeventmachine/EmReactor.java +1 -0
  46. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -40
  47. data/lib/em/buftok.rb +138 -138
  48. data/lib/em/callback.rb +25 -25
  49. data/lib/em/channel.rb +1 -1
  50. data/lib/em/connection.rb +6 -1
  51. data/lib/em/deferrable.rb +16 -2
  52. data/lib/em/file_watch.rb +53 -53
  53. data/lib/em/future.rb +61 -61
  54. data/lib/em/iterator.rb +270 -0
  55. data/lib/em/messages.rb +66 -66
  56. data/lib/em/process_watch.rb +43 -43
  57. data/lib/em/protocols.rb +1 -1
  58. data/lib/em/protocols/header_and_content.rb +138 -138
  59. data/lib/em/protocols/httpclient.rb +267 -262
  60. data/lib/em/protocols/line_protocol.rb +28 -0
  61. data/lib/em/protocols/memcache.rb +322 -322
  62. data/lib/em/protocols/postgres3.rb +247 -247
  63. data/lib/em/protocols/saslauth.rb +175 -175
  64. data/lib/em/protocols/smtpserver.rb +640 -547
  65. data/lib/em/protocols/stomp.rb +200 -200
  66. data/lib/em/protocols/tcptest.rb +52 -52
  67. data/lib/{pr_eventmachine.rb → em/pure_ruby.rb} +1013 -1022
  68. data/lib/em/queue.rb +1 -0
  69. data/lib/em/spawnable.rb +85 -85
  70. data/lib/em/streamer.rb +130 -130
  71. data/lib/em/tick_loop.rb +85 -0
  72. data/lib/em/timers.rb +2 -1
  73. data/lib/em/version.rb +1 -1
  74. data/lib/eventmachine.rb +40 -84
  75. data/lib/jeventmachine.rb +2 -1
  76. data/lib/rubyeventmachine.rb +2 -0
  77. data/setup.rb +1585 -1585
  78. data/tasks/doc.rake +30 -0
  79. data/tasks/package.rake +85 -0
  80. data/tasks/test.rake +6 -0
  81. data/tests/client.crt +31 -31
  82. data/tests/client.key +51 -51
  83. data/tests/test_attach.rb +13 -3
  84. data/tests/test_basic.rb +60 -95
  85. data/tests/test_channel.rb +3 -2
  86. data/tests/test_defer.rb +49 -47
  87. data/tests/test_deferrable.rb +35 -0
  88. data/tests/test_error_handler.rb +35 -35
  89. data/tests/test_errors.rb +82 -82
  90. data/tests/test_exc.rb +55 -55
  91. data/tests/test_file_watch.rb +49 -49
  92. data/tests/test_futures.rb +198 -198
  93. data/tests/test_handler_check.rb +36 -36
  94. data/tests/test_hc.rb +190 -218
  95. data/tests/test_httpclient.rb +227 -218
  96. data/tests/test_httpclient2.rb +3 -2
  97. data/tests/test_inactivity_timeout.rb +3 -3
  98. data/tests/test_kb.rb +60 -60
  99. data/tests/test_ltp.rb +13 -5
  100. data/tests/test_ltp2.rb +317 -317
  101. data/tests/test_next_tick.rb +1 -1
  102. data/tests/test_object_protocol.rb +36 -36
  103. data/tests/test_pending_connect_timeout.rb +2 -2
  104. data/tests/test_process_watch.rb +50 -48
  105. data/tests/test_proxy_connection.rb +52 -0
  106. data/tests/test_pure.rb +134 -125
  107. data/tests/test_queue.rb +44 -44
  108. data/tests/test_running.rb +42 -42
  109. data/tests/test_sasl.rb +72 -72
  110. data/tests/test_send_file.rb +251 -242
  111. data/tests/test_servers.rb +76 -76
  112. data/tests/test_smtpclient.rb +83 -83
  113. data/tests/test_smtpserver.rb +85 -85
  114. data/tests/test_spawn.rb +322 -322
  115. data/tests/test_ssl_methods.rb +49 -49
  116. data/tests/test_ssl_verify.rb +82 -82
  117. data/tests/test_tick_loop.rb +59 -0
  118. data/tests/test_timers.rb +13 -15
  119. data/tests/test_ud.rb +36 -36
  120. data/tests/testem.rb +31 -31
  121. metadata +66 -51
  122. data/ext/cplusplus.cpp +0 -202
  123. data/ext/emwin.cpp +0 -300
  124. data/ext/emwin.h +0 -94
  125. data/ext/epoll.cpp +0 -26
  126. data/ext/epoll.h +0 -25
  127. data/ext/eventmachine_cpp.h +0 -96
  128. data/ext/files.cpp +0 -94
  129. data/ext/files.h +0 -65
  130. data/ext/sigs.cpp +0 -89
  131. data/ext/sigs.h +0 -32
  132. data/java/src/com/rubyeventmachine/application/Application.java +0 -194
  133. data/java/src/com/rubyeventmachine/application/Connection.java +0 -74
  134. data/java/src/com/rubyeventmachine/application/ConnectionFactory.java +0 -37
  135. data/java/src/com/rubyeventmachine/application/DefaultConnectionFactory.java +0 -46
  136. data/java/src/com/rubyeventmachine/application/PeriodicTimer.java +0 -38
  137. data/java/src/com/rubyeventmachine/application/Timer.java +0 -54
  138. data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +0 -109
  139. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +0 -148
  140. data/java/src/com/rubyeventmachine/tests/EMTest.java +0 -80
  141. data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +0 -53
  142. data/java/src/com/rubyeventmachine/tests/TestServers.java +0 -75
  143. data/java/src/com/rubyeventmachine/tests/TestTimers.java +0 -90
  144. data/lib/evma.rb +0 -32
  145. data/lib/evma/callback.rb +0 -32
  146. data/lib/evma/container.rb +0 -75
  147. data/lib/evma/factory.rb +0 -77
  148. data/lib/evma/protocol.rb +0 -87
  149. data/lib/evma/reactor.rb +0 -48
  150. data/web/whatis +0 -7
@@ -1,133 +1,246 @@
1
- EventMachine (EM) adds two different formalisms for lightweight concurrency to the Ruby programmer's toolbox: spawned processes and deferrables. This note will show you how to use deferrables. For more information, see the separate document LIGHTWEIGHT_CONCURRENCY.
2
-
3
- === What are Deferrables?
4
-
5
- EventMachine's Deferrable borrows heavily from the "deferred" object in Python's "Twisted" event-handling framework. Here's a minimal example that illustrates Deferrable:
6
-
7
- require 'eventmachine'
8
-
9
- class MyClass
10
- include EM::Deferrable
11
-
12
- def print_value x
13
- puts "MyClass instance received #{x}"
14
- end
15
- end
16
-
17
- EM.run {
18
- df = MyClass.new
19
- df.callback {|x|
20
- df.print_value(x)
21
- EM.stop
22
- }
23
-
24
- EM::Timer.new(2) {
25
- df.set_deferred_status :succeeded, 100
26
- }
27
- }
28
-
29
-
30
- This program will spin for two seconds, print out the string "MyClass instance received 100" and then exit. The Deferrable pattern relies on an unusual metaphor that may be unfamiliar to you, unless you've used Python's Twisted. You may need to read the following material through more than once before you get the idea.
31
-
32
- EventMachine::Deferrable is simply a Ruby Module that you can include in your own classes. (There also is a class named EventMachine::DefaultDeferrable for when you want to create one without including it in code of your own.)
33
-
34
- An object that includes EventMachine::Deferrable is like any other Ruby object: it can be created whenever you want, returned from your functions, or passed as an argument to other functions.
35
-
36
- The Deferrable pattern allows you to specify any number of Ruby code blocks (callbacks or errbacks) that will be executed at some future time when the status of the Deferrable object changes.
37
-
38
- How might that be useful? Well, imagine that you're implementing an HTTP server, but you need to make a call to some other server in order to fulfill a client request.
39
-
40
- When you receive a request from one of your clients, you can create and return a Deferrable object. Some other section of your program can add a callback to the Deferrable that will cause the client's request to be fulfilled. Simultaneously, you initiate an event-driven or threaded client request to some different server. And then your EM program will continue to process other events and service other client requests.
41
-
42
- When your client request to the other server completes some time later, you will call the #set_deferred_status method on the Deferrable object, passing either a success or failure status, and an arbitrary number of parameters (which might include the data you received from the other server).
43
-
44
- At that point, the status of the Deferrable object becomes known, and its callback or errback methods are immediately executed. Callbacks and errbacks are code blocks that are attached to Deferrable objects at any time through the methods #callback and #errback.
45
-
46
- The deep beauty of this pattern is that it decouples the disposition of one operation (such as a client request to an outboard server) from the subsequent operations that depend on that disposition (which may include responding to a different client or any other operation).
47
-
48
- The code which invokes the deferred operation (that will eventually result in a success or failure status together with associated data) is completely separate from the code which depends on that status and data. This achieves one of the primary goals for which threading is typically used in sophisticated applications, with none of the nondeterminacy or debugging difficulties of threads.
49
-
50
- As soon as the deferred status of a Deferrable becomes known by way of a call to #set_deferred_status, the Deferrable will IMMEDIATELY execute all of its callbacks or errbacks in the order in which they were added to the Deferrable.
51
-
52
- Callbacks and errbacks can be added to a Deferrable object at any time, not just when the object is created. They can even be added after the status of the object has been determined! (In this case, they will be executed immediately when they are added.)
53
-
54
- A call to Deferrable#set_deferred_status takes :succeeded or :failed as its first argument. (This determines whether the object will call its callbacks or its errbacks.) #set_deferred_status also takes zero or more additional parameters, that will in turn be passed as parameters to the callbacks or errbacks.
55
-
56
- In general, you can only call #set_deferred_status ONCE on a Deferrable object. A call to #set_deferred_status will not return until all of the associated callbacks or errbacks have been called. If you add callbacks or errbacks AFTER making a call to #set_deferred_status, those additional callbacks or errbacks will execute IMMEDIATELY. Any given callback or errback will be executed AT MOST once.
57
-
58
- It's possible to call #set_deferred_status AGAIN, during the execution a callback or errback. This makes it possible to change the parameters which will be sent to the callbacks or errbacks farther down the chain, enabling some extremely elegant use-cases. You can transform the data returned from a deferred operation in arbitrary ways as needed by subsequent users, without changing any of the code that generated the original data.
59
-
60
- A call to #set_deferred_status will not return until all of the associated callbacks or errbacks have been called. If you add callbacks or errbacks AFTER making a call to #set_deferred_status, those additional callbacks or errbacks will execute IMMEDIATELY.
61
-
62
- Let's look at some more sample code. It turns out that many of the internal protocol implementations in the EventMachine package rely on Deferrable. One of these is EM::Protocols::HttpClient.
63
-
64
- To make an evented HTTP request, use the module function EM::Protocols::HttpClient#request, which returns a Deferrable object. Here's how:
65
-
66
- require 'eventmachine'
67
-
68
- EM.run {
69
- df = EM::Protocols::HttpClient.request( :host=>"www.example.com", :request=>"/index.html" )
70
-
71
- df.callback {|response|
72
- puts "Succeeded: #{response[:content]}"
73
- EM.stop
74
- }
75
-
76
- df.errback {|response|
77
- puts "ERROR: #{response[:status]}"
78
- EM.stop
79
- }
80
- }
81
-
82
- (See the documentation of EventMachine::Protocols::HttpClient for information on the object returned by #request.)
83
-
84
- In this code, we make a call to HttpClient#request, which immediately returns a Deferrable object. In the background, an HTTP client request is being made to www.example.com, although your code will continue to run concurrently.
85
-
86
- At some future point, the HTTP client request will complete, and the code in EM::Protocols::HttpClient will process either a valid HTTP response (including returned content), or an error.
87
-
88
- At that point, EM::Protocols::HttpClient will call EM::Deferrable#set_deferred_status on the Deferrable object that was returned to your program, as the return value from EM::Protocols::HttpClient.request. You don't have to do anything to make this happen. All you have to do is tell the Deferrable what to do in case of either success, failure, or both.
89
-
90
- In our code sample, we set one callback and one errback. The former will be called if the HTTP call succeeds, and the latter if it fails. (For simplicity, we have both of them calling EM#stop to end the program, although real programs would be very unlikely to do this.)
91
-
92
- Setting callbacks and errbacks is optional. They are handlers to defined events in the lifecycle of the Deferrable event. It's not an error if you fail to set either a callback, an errback, or both. But of course your program will then fail to receive those notifications.
93
-
94
- If through some bug it turns out that #set_deferred_status is never called on a Deferrable object, then that object's callbacks or errbacks will NEVER be called. It's also possible to set a timeout on a Deferrable. If the timeout elapses before any other call to #set_deferred_status, the Deferrable object will behave as is you had called set_deferred_status(:failed) on it.
95
-
96
-
97
- Now let's modify the example to illustrate some additional points:
98
-
99
- require 'eventmachine'
100
-
101
- EM.run {
102
- df = EM::Protocols::HttpClient.request( :host=>"www.example.com", :request=>"/index.html" )
103
-
104
- df.callback {|response|
105
- df.set_deferred_status :succeeded, response[:content]
106
- }
107
-
108
- df.callback {|string|
109
- puts "Succeeded: #{string}"
110
- EM.stop
111
- }
112
-
113
- df.errback {|response|
114
- puts "ERROR: #{response[:status]}"
115
- EM.stop
116
- }
117
- }
118
-
119
-
120
- Just for the sake of illustration, we've now set two callbacks instead of one. If the deferrable operation (the HTTP client-request) succeeds, then both of the callbacks will be executed in order.
121
-
122
- But notice that we've also made our own call to #set_deferred_status in the first callback. This isn't required, because the HttpClient implementation already made a call to #set_deferred_status. (Otherwise, of course, the callback would not be executing.)
123
-
124
- But we used #set_deferred_status in the first callback in order to change the parameters that will be sent to subsequent callbacks in the chain. In this way, you can construct powerful sequences of layered functionality. If you want, you can even change the status of the Deferrable from :succeeded to :failed, which would abort the chain of callback calls, and invoke the chain of errbacks instead.
125
-
126
- Now of course it's somewhat trivial to define two callbacks in the same method, even with the parameter-changing effect we just described. It would be much more interesting to pass the Deferrable to some other function (for example, a function defined in another module or a different gem), that would in turn add callbacks and/or errbacks of its own. That would illustrate the true power of the Deferrable pattern: to isolate the HTTP client-request from other functions that use the data that it returns without caring where those data came from.
127
-
128
- Remember that you can add a callback or an errback to a Deferrable at any point in time, regardless of whether the status of the deferred operation is known (more precisely, regardless of when #set_deferred_status is called on the object). Even hours or days later.
129
-
130
- When you add a callback or errback to a Deferrable object on which #set_deferred_status has not yet been called, the callback/errback is queued up for future execution, inside the Deferrable object. When you add a callback or errback to a Deferrable on which #set_deferred_status has already been called, the callback/errback will be executed immediately. Your code doesn't have to worry about the ordering, and there are no timing issues, as there would be with a threaded approach.
131
-
132
- For more information on Deferrables and their typical usage patterns, look in the EM unit tests. There are also quite a few sugarings (including EM::Deferrable#future) that make typical Deferrable usages syntactically easier to work with.
133
-
1
+ EventMachine (EM) adds two different formalisms for lightweight concurrency
2
+ to the Ruby programmer's toolbox: spawned processes and deferrables. This
3
+ note will show you how to use deferrables. For more information, see the
4
+ separate document LIGHTWEIGHT_CONCURRENCY.
5
+
6
+ === What are Deferrables?
7
+
8
+ EventMachine's Deferrable borrows heavily from the "deferred" object in
9
+ Python's "Twisted" event-handling framework. Here's a minimal example that
10
+ illustrates Deferrable:
11
+
12
+ require 'eventmachine'
13
+
14
+ class MyClass
15
+ include EM::Deferrable
16
+
17
+ def print_value x
18
+ puts "MyClass instance received #{x}"
19
+ end
20
+ end
21
+
22
+ EM.run {
23
+ df = MyClass.new
24
+ df.callback {|x|
25
+ df.print_value(x)
26
+ EM.stop
27
+ }
28
+
29
+ EM::Timer.new(2) {
30
+ df.set_deferred_status :succeeded, 100
31
+ }
32
+ }
33
+
34
+
35
+ This program will spin for two seconds, print out the string "MyClass
36
+ instance received 100" and then exit. The Deferrable pattern relies on
37
+ an unusual metaphor that may be unfamiliar to you, unless you've used
38
+ Python's Twisted. You may need to read the following material through
39
+ more than once before you get the idea.
40
+
41
+ EventMachine::Deferrable is simply a Ruby Module that you can include
42
+ in your own classes. (There also is a class named
43
+ EventMachine::DefaultDeferrable for when you want to create one without
44
+ including it in code of your own.)
45
+
46
+ An object that includes EventMachine::Deferrable is like any other Ruby
47
+ object: it can be created whenever you want, returned from your functions,
48
+ or passed as an argument to other functions.
49
+
50
+ The Deferrable pattern allows you to specify any number of Ruby code
51
+ blocks (callbacks or errbacks) that will be executed at some future time
52
+ when the status of the Deferrable object changes.
53
+
54
+ How might that be useful? Well, imagine that you're implementing an HTTP
55
+ server, but you need to make a call to some other server in order to fulfill
56
+ a client request.
57
+
58
+ When you receive a request from one of your clients, you can create and
59
+ return a Deferrable object. Some other section of your program can add a
60
+ callback to the Deferrable that will cause the client's request to be
61
+ fulfilled. Simultaneously, you initiate an event-driven or threaded client
62
+ request to some different server. And then your EM program will continue to
63
+ process other events and service other client requests.
64
+
65
+ When your client request to the other server completes some time later, you
66
+ will call the #set_deferred_status method on the Deferrable object, passing
67
+ either a success or failure status, and an arbitrary number of parameters
68
+ (which might include the data you received from the other server).
69
+
70
+ At that point, the status of the Deferrable object becomes known, and its
71
+ callback or errback methods are immediately executed. Callbacks and errbacks
72
+ are code blocks that are attached to Deferrable objects at any time through
73
+ the methods #callback and #errback.
74
+
75
+ The deep beauty of this pattern is that it decouples the disposition of one
76
+ operation (such as a client request to an outboard server) from the
77
+ subsequent operations that depend on that disposition (which may include
78
+ responding to a different client or any other operation).
79
+
80
+ The code which invokes the deferred operation (that will eventually result
81
+ in a success or failure status together with associated data) is completely
82
+ separate from the code which depends on that status and data. This achieves
83
+ one of the primary goals for which threading is typically used in
84
+ sophisticated applications, with none of the nondeterminacy or debugging
85
+ difficulties of threads.
86
+
87
+ As soon as the deferred status of a Deferrable becomes known by way of a call
88
+ to #set_deferred_status, the Deferrable will IMMEDIATELY execute all of its
89
+ callbacks or errbacks in the order in which they were added to the Deferrable.
90
+
91
+ Callbacks and errbacks can be added to a Deferrable object at any time, not
92
+ just when the object is created. They can even be added after the status of
93
+ the object has been determined! (In this case, they will be executed
94
+ immediately when they are added.)
95
+
96
+ A call to Deferrable#set_deferred_status takes :succeeded or :failed as its
97
+ first argument. (This determines whether the object will call its callbacks
98
+ or its errbacks.) #set_deferred_status also takes zero or more additional
99
+ parameters, that will in turn be passed as parameters to the callbacks or
100
+ errbacks.
101
+
102
+ In general, you can only call #set_deferred_status ONCE on a Deferrable
103
+ object. A call to #set_deferred_status will not return until all of the
104
+ associated callbacks or errbacks have been called. If you add callbacks or
105
+ errbacks AFTER making a call to #set_deferred_status, those additional
106
+ callbacks or errbacks will execute IMMEDIATELY. Any given callback or
107
+ errback will be executed AT MOST once.
108
+
109
+ It's possible to call #set_deferred_status AGAIN, during the execution a
110
+ callback or errback. This makes it possible to change the parameters which
111
+ will be sent to the callbacks or errbacks farther down the chain, enabling
112
+ some extremely elegant use-cases. You can transform the data returned from
113
+ a deferred operation in arbitrary ways as needed by subsequent users, without
114
+ changing any of the code that generated the original data.
115
+
116
+ A call to #set_deferred_status will not return until all of the associated
117
+ callbacks or errbacks have been called. If you add callbacks or errbacks
118
+ AFTER making a call to #set_deferred_status, those additional callbacks or
119
+ errbacks will execute IMMEDIATELY.
120
+
121
+ Let's look at some more sample code. It turns out that many of the internal
122
+ protocol implementations in the EventMachine package rely on Deferrable. One
123
+ of these is EM::Protocols::HttpClient.
124
+
125
+ To make an evented HTTP request, use the module function
126
+ EM::Protocols::HttpClient#request, which returns a Deferrable object.
127
+ Here's how:
128
+
129
+ require 'eventmachine'
130
+
131
+ EM.run {
132
+ df = EM::Protocols::HttpClient.request( :host=>"www.example.com",
133
+ :request=>"/index.html" )
134
+
135
+ df.callback {|response|
136
+ puts "Succeeded: #{response[:content]}"
137
+ EM.stop
138
+ }
139
+
140
+ df.errback {|response|
141
+ puts "ERROR: #{response[:status]}"
142
+ EM.stop
143
+ }
144
+ }
145
+
146
+ (See the documentation of EventMachine::Protocols::HttpClient for information
147
+ on the object returned by #request.)
148
+
149
+ In this code, we make a call to HttpClient#request, which immediately returns
150
+ a Deferrable object. In the background, an HTTP client request is being made
151
+ to www.example.com, although your code will continue to run concurrently.
152
+
153
+ At some future point, the HTTP client request will complete, and the code in
154
+ EM::Protocols::HttpClient will process either a valid HTTP response (including
155
+ returned content), or an error.
156
+
157
+ At that point, EM::Protocols::HttpClient will call
158
+ EM::Deferrable#set_deferred_status on the Deferrable object that was returned
159
+ to your program, as the return value from EM::Protocols::HttpClient.request.
160
+ You don't have to do anything to make this happen. All you have to do is tell
161
+ the Deferrable what to do in case of either success, failure, or both.
162
+
163
+ In our code sample, we set one callback and one errback. The former will be
164
+ called if the HTTP call succeeds, and the latter if it fails. (For
165
+ simplicity, we have both of them calling EM#stop to end the program, although
166
+ real programs would be very unlikely to do this.)
167
+
168
+ Setting callbacks and errbacks is optional. They are handlers to defined
169
+ events in the lifecycle of the Deferrable event. It's not an error if you
170
+ fail to set either a callback, an errback, or both. But of course your
171
+ program will then fail to receive those notifications.
172
+
173
+ If through some bug it turns out that #set_deferred_status is never called
174
+ on a Deferrable object, then that object's callbacks or errbacks will NEVER
175
+ be called. It's also possible to set a timeout on a Deferrable. If the
176
+ timeout elapses before any other call to #set_deferred_status, the Deferrable
177
+ object will behave as is you had called set_deferred_status(:failed) on it.
178
+
179
+
180
+ Now let's modify the example to illustrate some additional points:
181
+
182
+ require 'eventmachine'
183
+
184
+ EM.run {
185
+ df = EM::Protocols::HttpClient.request( :host=>"www.example.com",
186
+ :request=>"/index.html" )
187
+
188
+ df.callback {|response|
189
+ df.set_deferred_status :succeeded, response[:content]
190
+ }
191
+
192
+ df.callback {|string|
193
+ puts "Succeeded: #{string}"
194
+ EM.stop
195
+ }
196
+
197
+ df.errback {|response|
198
+ puts "ERROR: #{response[:status]}"
199
+ EM.stop
200
+ }
201
+ }
202
+
203
+
204
+ Just for the sake of illustration, we've now set two callbacks instead of
205
+ one. If the deferrable operation (the HTTP client-request) succeeds, then
206
+ both of the callbacks will be executed in order.
207
+
208
+ But notice that we've also made our own call to #set_deferred_status in the
209
+ first callback. This isn't required, because the HttpClient implementation
210
+ already made a call to #set_deferred_status. (Otherwise, of course, the
211
+ callback would not be executing.)
212
+
213
+ But we used #set_deferred_status in the first callback in order to change the
214
+ parameters that will be sent to subsequent callbacks in the chain. In this
215
+ way, you can construct powerful sequences of layered functionality. If you
216
+ want, you can even change the status of the Deferrable from :succeeded to
217
+ :failed, which would abort the chain of callback calls, and invoke the chain
218
+ of errbacks instead.
219
+
220
+ Now of course it's somewhat trivial to define two callbacks in the same
221
+ method, even with the parameter-changing effect we just described. It would
222
+ be much more interesting to pass the Deferrable to some other function (for
223
+ example, a function defined in another module or a different gem), that would
224
+ in turn add callbacks and/or errbacks of its own. That would illustrate the
225
+ true power of the Deferrable pattern: to isolate the HTTP client-request
226
+ from other functions that use the data that it returns without caring where
227
+ those data came from.
228
+
229
+ Remember that you can add a callback or an errback to a Deferrable at any
230
+ point in time, regardless of whether the status of the deferred operation is
231
+ known (more precisely, regardless of when #set_deferred_status is called on
232
+ the object). Even hours or days later.
233
+
234
+ When you add a callback or errback to a Deferrable object on which
235
+ #set_deferred_status has not yet been called, the callback/errback is queued
236
+ up for future execution, inside the Deferrable object. When you add a
237
+ callback or errback to a Deferrable on which #set_deferred_status has
238
+ already been called, the callback/errback will be executed immediately.
239
+ Your code doesn't have to worry about the ordering, and there are no timing
240
+ issues, as there would be with a threaded approach.
241
+
242
+ For more information on Deferrables and their typical usage patterns, look
243
+ in the EM unit tests. There are also quite a few sugarings (including
244
+ EM::Deferrable#future) that make typical Deferrable usages syntactically
245
+ easier to work with.
246
+
data/docs/EPOLL CHANGED
@@ -1,141 +1,141 @@
1
- EventMachine now supports epoll, bringing large increases in performance and scalability to Ruby programs.
2
-
3
- Epoll(7) is a alternative mechanism for multiplexed I/O that is available in Linux 2.6 kernels.
4
- It features significantly greater performance than the standard select(2) mechanism, when used in
5
- applications that require very large numbers of open I/O descriptors.
6
-
7
- EventMachine has always used select(2) because its behavior is well standardized and broadly supported.
8
- But select becomes unreasonably slow when a program has a
9
- very large number of file descriptors or sockets. Ruby's version of select hardcodes a limit
10
- of 1024 descriptors per process, but heavily loaded processes will start to show performance
11
- degradation even after only a few hundred descriptors are in use.
12
-
13
- Epoll is an extended version of the poll(2) call, and it solves the problems with select. Programs
14
- based on epoll can easily scale past Ruby's 1024-descriptor limit, potentially to tens of thousands
15
- of connectors, with no significant impact on performance.
16
-
17
- (Another alternative which is very similar to epoll in principle is kqueue, supplied on BSD and its
18
- variants.)
19
-
20
-
21
-
22
- This note shows you how to use epoll in your programs.
23
-
24
- === Compiling EventMachine to use epoll.
25
-
26
- You don't have to do anything to get epoll support in EventMachine.
27
- When you compile EventMachine on a platform that supports epoll, EM will
28
- automatically generate a Makefile that includes epoll. (At this writing, this will only work
29
- on Linux 2.6 kernels.) If you compile EM on a platform without epoll, then epoll support will
30
- be omitted from the Makefile, and EM will work just as it always has.
31
-
32
- === Using epoll in your programs.
33
-
34
- First, you need to tell EventMachine to use epoll instead of select (but see below, as this requirement
35
- will be removed in a future EventMachine version). Second, you need to prepare your program to use
36
- more than 1024 descriptors, an operation that generally requires superuser privileges. Third, you will probably
37
- want your process to drop the superuser privileges after you increase your process's descriptor limit.
38
-
39
- === Using EventMachine#epoll
40
-
41
- Call the method EventMachine#epoll anytime before you call EventMachine#run, and your program will
42
- automatically use epoll, if available. It's safe to call EventMachine#epoll on any platform because
43
- it compiles to a no-op on platforms that don't support epoll.
44
-
45
- require 'rubygems'
46
- require 'eventmachine'
47
-
48
- EM.epoll
49
- EM.run {
50
- ...
51
- }
52
-
53
-
54
- EventMachine#epoll was included in this initial release only to avoid changing the behavior of existing
55
- programs. However, it's expected that a future release of EM will convert EventMachine#epoll to a no-op,
56
- and run epoll by default on platforms that support it.
57
-
58
- === Using EventMachine#set_descriptor_table_size
59
-
60
- In Linux (as in every Unix-like platform), every process has a internal table that determines the maximum
61
- number of file and socket descriptors you may have open at any given time. The size of this table is
62
- generally fixed at 1024, although it may be increased within certain system-defined hard and soft limits.
63
-
64
- If you want your EventMachine program to support more than 1024 total descriptors, you must use
65
- EventMachine#set_descriptor_table_size, as follows:
66
-
67
- require 'rubygems'
68
- require 'eventmachine'
69
-
70
- new_size = EM.set_descriptor_table_size( 60000 )
71
- $>.puts "New descriptor-table size is #{new_size}"
72
-
73
- EM.run {
74
- ...
75
- }
76
-
77
- If successful, this example will increase the maximum number of descriptors that epoll can use to 60,000.
78
- Call EventMachine#set_descriptor_table_size without an argument at any time to find out the current
79
- size of the descriptor table.
80
-
81
- Using EventMachine#set_descriptor_table_size ONLY affects the number of descriptors that can be used
82
- by epoll. It has no useful effect on platforms that don't support epoll, and it does NOT increase the
83
- number of descriptors that Ruby's own I/O functions can use.
84
-
85
- #set_descriptor_table_size can fail if your process is not running as superuser, or if you try to set a
86
- table size that exceeds the hard limits imposed by your system. In the latter case, try a smaller number.
87
-
88
-
89
- === Using EventMachine#set_effective_user
90
-
91
- In general, you must run your program with elevated or superuser privileges if you want to increase
92
- your descriptor-table size beyond 1024 descriptors. This is easy enough to verify. Try running the
93
- sample program given above, that increases the descriptor limit to 60,000. You will probably find that
94
- the table size will not be increased if you don't run your program as root or with elevated privileges.
95
-
96
- But of course network servers, especially long-running ones, should not run with elevated privileges.
97
- You will want to drop superuser privileges as soon as possible after initialization. To do this,
98
- use EventMachine#set_effective_user:
99
-
100
- require 'rubygems'
101
- require 'eventmachine'
102
-
103
- # (Here, program is running as superuser)
104
-
105
- EM.set_descriptor_table_size( 60000 )
106
- EM.set_effective_user( "nobody" )
107
- # (Here, program is running as nobody)
108
-
109
- EM.run {
110
- ...
111
- }
112
-
113
- Of course, you will need to replace "nobody" in the example with the name of an unprivileged user
114
- that is valid on your system. What if you want to drop privileges after opening a server socket
115
- on a privileged (low-numbered) port? Easy, just call #set_effective_user after opening your sockets:
116
-
117
- require 'rubygems'
118
- require 'eventmachine'
119
-
120
- # (Here, program is running as superuser)
121
-
122
- EM.set_descriptor_table_size( 60000 )
123
-
124
- EM.run {
125
- EM.start_server( "0.0.0.0", 80, MyHttpServer )
126
- EM.start_server( "0.0.0.0", 443, MyEncryptedHttpServer )
127
-
128
- EM.set_effective_user( "nobody" )
129
- # (Here, program is running as nobody)
130
-
131
- ...
132
- }
133
-
134
-
135
- Because EventMachine#set_effective_user is used to enforce security
136
- requirements, it has no nonfatal errors. If you try to set a nonexistent or invalid effective user,
137
- #set_effective_user will abort your program, rather than continue to run with elevated privileges.
138
-
139
- EventMachine#set_effective_user is a silent no-op on platforms that don't support it, such as Windows.
140
-
141
-
1
+ EventMachine now supports epoll, bringing large increases in performance and scalability to Ruby programs.
2
+
3
+ Epoll(7) is a alternative mechanism for multiplexed I/O that is available in Linux 2.6 kernels.
4
+ It features significantly greater performance than the standard select(2) mechanism, when used in
5
+ applications that require very large numbers of open I/O descriptors.
6
+
7
+ EventMachine has always used select(2) because its behavior is well standardized and broadly supported.
8
+ But select becomes unreasonably slow when a program has a
9
+ very large number of file descriptors or sockets. Ruby's version of select hardcodes a limit
10
+ of 1024 descriptors per process, but heavily loaded processes will start to show performance
11
+ degradation even after only a few hundred descriptors are in use.
12
+
13
+ Epoll is an extended version of the poll(2) call, and it solves the problems with select. Programs
14
+ based on epoll can easily scale past Ruby's 1024-descriptor limit, potentially to tens of thousands
15
+ of connectors, with no significant impact on performance.
16
+
17
+ (Another alternative which is very similar to epoll in principle is kqueue, supplied on BSD and its
18
+ variants.)
19
+
20
+
21
+
22
+ This note shows you how to use epoll in your programs.
23
+
24
+ === Compiling EventMachine to use epoll.
25
+
26
+ You don't have to do anything to get epoll support in EventMachine.
27
+ When you compile EventMachine on a platform that supports epoll, EM will
28
+ automatically generate a Makefile that includes epoll. (At this writing, this will only work
29
+ on Linux 2.6 kernels.) If you compile EM on a platform without epoll, then epoll support will
30
+ be omitted from the Makefile, and EM will work just as it always has.
31
+
32
+ === Using epoll in your programs.
33
+
34
+ First, you need to tell EventMachine to use epoll instead of select (but see below, as this requirement
35
+ will be removed in a future EventMachine version). Second, you need to prepare your program to use
36
+ more than 1024 descriptors, an operation that generally requires superuser privileges. Third, you will probably
37
+ want your process to drop the superuser privileges after you increase your process's descriptor limit.
38
+
39
+ === Using EventMachine#epoll
40
+
41
+ Call the method EventMachine#epoll anytime before you call EventMachine#run, and your program will
42
+ automatically use epoll, if available. It's safe to call EventMachine#epoll on any platform because
43
+ it compiles to a no-op on platforms that don't support epoll.
44
+
45
+ require 'rubygems'
46
+ require 'eventmachine'
47
+
48
+ EM.epoll
49
+ EM.run {
50
+ ...
51
+ }
52
+
53
+
54
+ EventMachine#epoll was included in this initial release only to avoid changing the behavior of existing
55
+ programs. However, it's expected that a future release of EM will convert EventMachine#epoll to a no-op,
56
+ and run epoll by default on platforms that support it.
57
+
58
+ === Using EventMachine#set_descriptor_table_size
59
+
60
+ In Linux (as in every Unix-like platform), every process has a internal table that determines the maximum
61
+ number of file and socket descriptors you may have open at any given time. The size of this table is
62
+ generally fixed at 1024, although it may be increased within certain system-defined hard and soft limits.
63
+
64
+ If you want your EventMachine program to support more than 1024 total descriptors, you must use
65
+ EventMachine#set_descriptor_table_size, as follows:
66
+
67
+ require 'rubygems'
68
+ require 'eventmachine'
69
+
70
+ new_size = EM.set_descriptor_table_size( 60000 )
71
+ $>.puts "New descriptor-table size is #{new_size}"
72
+
73
+ EM.run {
74
+ ...
75
+ }
76
+
77
+ If successful, this example will increase the maximum number of descriptors that epoll can use to 60,000.
78
+ Call EventMachine#set_descriptor_table_size without an argument at any time to find out the current
79
+ size of the descriptor table.
80
+
81
+ Using EventMachine#set_descriptor_table_size ONLY affects the number of descriptors that can be used
82
+ by epoll. It has no useful effect on platforms that don't support epoll, and it does NOT increase the
83
+ number of descriptors that Ruby's own I/O functions can use.
84
+
85
+ #set_descriptor_table_size can fail if your process is not running as superuser, or if you try to set a
86
+ table size that exceeds the hard limits imposed by your system. In the latter case, try a smaller number.
87
+
88
+
89
+ === Using EventMachine#set_effective_user
90
+
91
+ In general, you must run your program with elevated or superuser privileges if you want to increase
92
+ your descriptor-table size beyond 1024 descriptors. This is easy enough to verify. Try running the
93
+ sample program given above, that increases the descriptor limit to 60,000. You will probably find that
94
+ the table size will not be increased if you don't run your program as root or with elevated privileges.
95
+
96
+ But of course network servers, especially long-running ones, should not run with elevated privileges.
97
+ You will want to drop superuser privileges as soon as possible after initialization. To do this,
98
+ use EventMachine#set_effective_user:
99
+
100
+ require 'rubygems'
101
+ require 'eventmachine'
102
+
103
+ # (Here, program is running as superuser)
104
+
105
+ EM.set_descriptor_table_size( 60000 )
106
+ EM.set_effective_user( "nobody" )
107
+ # (Here, program is running as nobody)
108
+
109
+ EM.run {
110
+ ...
111
+ }
112
+
113
+ Of course, you will need to replace "nobody" in the example with the name of an unprivileged user
114
+ that is valid on your system. What if you want to drop privileges after opening a server socket
115
+ on a privileged (low-numbered) port? Easy, just call #set_effective_user after opening your sockets:
116
+
117
+ require 'rubygems'
118
+ require 'eventmachine'
119
+
120
+ # (Here, program is running as superuser)
121
+
122
+ EM.set_descriptor_table_size( 60000 )
123
+
124
+ EM.run {
125
+ EM.start_server( "0.0.0.0", 80, MyHttpServer )
126
+ EM.start_server( "0.0.0.0", 443, MyEncryptedHttpServer )
127
+
128
+ EM.set_effective_user( "nobody" )
129
+ # (Here, program is running as nobody)
130
+
131
+ ...
132
+ }
133
+
134
+
135
+ Because EventMachine#set_effective_user is used to enforce security
136
+ requirements, it has no nonfatal errors. If you try to set a nonexistent or invalid effective user,
137
+ #set_effective_user will abort your program, rather than continue to run with elevated privileges.
138
+
139
+ EventMachine#set_effective_user is a silent no-op on platforms that don't support it, such as Windows.
140
+
141
+