eventmachine 0.12.6-java → 0.12.8-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. data/{docs/README → README} +21 -13
  2. data/Rakefile +5 -3
  3. data/docs/DEFERRABLES +0 -5
  4. data/docs/INSTALL +2 -4
  5. data/docs/LEGAL +1 -1
  6. data/docs/LIGHTWEIGHT_CONCURRENCY +0 -2
  7. data/docs/PURE_RUBY +0 -2
  8. data/docs/RELEASE_NOTES +0 -2
  9. data/docs/SMTP +0 -7
  10. data/docs/SPAWNED_PROCESSES +0 -4
  11. data/docs/TODO +0 -2
  12. data/eventmachine.gemspec +17 -8
  13. data/examples/ex_channel.rb +43 -0
  14. data/examples/ex_queue.rb +2 -0
  15. data/examples/helper.rb +2 -0
  16. data/ext/cmain.cpp +119 -20
  17. data/ext/cplusplus.cpp +15 -6
  18. data/ext/ed.cpp +303 -93
  19. data/ext/ed.h +49 -22
  20. data/ext/em.cpp +368 -42
  21. data/ext/em.h +43 -6
  22. data/ext/eventmachine.h +21 -8
  23. data/ext/eventmachine_cpp.h +1 -0
  24. data/ext/extconf.rb +4 -0
  25. data/ext/kb.cpp +1 -2
  26. data/ext/pipe.cpp +1 -3
  27. data/ext/project.h +21 -0
  28. data/ext/rubymain.cpp +232 -32
  29. data/ext/ssl.cpp +38 -1
  30. data/ext/ssl.h +5 -1
  31. data/java/src/com/rubyeventmachine/Application.java +7 -3
  32. data/java/src/com/rubyeventmachine/EmReactor.java +16 -1
  33. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +25 -3
  34. data/lib/{protocols → em}/buftok.rb +16 -5
  35. data/lib/em/callback.rb +26 -0
  36. data/lib/em/channel.rb +57 -0
  37. data/lib/em/connection.rb +505 -0
  38. data/lib/em/deferrable.rb +144 -165
  39. data/lib/em/file_watch.rb +54 -0
  40. data/lib/em/future.rb +24 -25
  41. data/lib/em/messages.rb +1 -1
  42. data/lib/em/process_watch.rb +44 -0
  43. data/lib/em/processes.rb +58 -52
  44. data/lib/em/protocols.rb +35 -0
  45. data/lib/em/protocols/header_and_content.rb +138 -0
  46. data/lib/em/protocols/httpclient.rb +263 -0
  47. data/lib/em/protocols/httpclient2.rb +582 -0
  48. data/lib/{protocols → em/protocols}/line_and_text.rb +2 -2
  49. data/lib/em/protocols/linetext2.rb +160 -0
  50. data/lib/{protocols → em/protocols}/memcache.rb +37 -7
  51. data/lib/em/protocols/object_protocol.rb +39 -0
  52. data/lib/em/protocols/postgres3.rb +247 -0
  53. data/lib/em/protocols/saslauth.rb +175 -0
  54. data/lib/em/protocols/smtpclient.rb +331 -0
  55. data/lib/em/protocols/smtpserver.rb +547 -0
  56. data/lib/em/protocols/stomp.rb +200 -0
  57. data/lib/{protocols → em/protocols}/tcptest.rb +21 -25
  58. data/lib/em/queue.rb +61 -0
  59. data/lib/em/spawnable.rb +53 -56
  60. data/lib/em/streamer.rb +92 -74
  61. data/lib/em/timers.rb +55 -0
  62. data/lib/em/version.rb +3 -0
  63. data/lib/eventmachine.rb +1008 -1298
  64. data/lib/evma.rb +1 -1
  65. data/lib/jeventmachine.rb +106 -101
  66. data/lib/pr_eventmachine.rb +47 -36
  67. data/tasks/project.rake +2 -1
  68. data/tests/client.crt +31 -0
  69. data/tests/client.key +51 -0
  70. data/tests/test_attach.rb +18 -0
  71. data/tests/test_basic.rb +108 -54
  72. data/tests/test_channel.rb +63 -0
  73. data/tests/test_connection_count.rb +2 -2
  74. data/tests/test_epoll.rb +109 -110
  75. data/tests/test_errors.rb +36 -36
  76. data/tests/test_exc.rb +22 -25
  77. data/tests/test_file_watch.rb +49 -0
  78. data/tests/test_futures.rb +77 -93
  79. data/tests/test_hc.rb +2 -2
  80. data/tests/test_httpclient.rb +55 -52
  81. data/tests/test_httpclient2.rb +110 -112
  82. data/tests/test_inactivity_timeout.rb +30 -0
  83. data/tests/test_kb.rb +8 -9
  84. data/tests/test_ltp2.rb +274 -277
  85. data/tests/test_next_tick.rb +91 -65
  86. data/tests/test_object_protocol.rb +37 -0
  87. data/tests/test_process_watch.rb +48 -0
  88. data/tests/test_processes.rb +56 -23
  89. data/tests/test_proxy_connection.rb +92 -0
  90. data/tests/test_pure.rb +1 -5
  91. data/tests/test_queue.rb +44 -0
  92. data/tests/test_running.rb +9 -14
  93. data/tests/test_sasl.rb +32 -34
  94. data/tests/test_send_file.rb +175 -176
  95. data/tests/test_servers.rb +37 -41
  96. data/tests/test_smtpserver.rb +47 -55
  97. data/tests/test_spawn.rb +284 -291
  98. data/tests/test_ssl_args.rb +1 -1
  99. data/tests/test_ssl_methods.rb +1 -1
  100. data/tests/test_ssl_verify.rb +82 -0
  101. data/tests/test_timers.rb +81 -88
  102. data/tests/test_ud.rb +0 -7
  103. data/tests/testem.rb +1 -1
  104. metadata +52 -36
  105. data/lib/em/eventable.rb +0 -39
  106. data/lib/eventmachine_version.rb +0 -31
  107. data/lib/protocols/header_and_content.rb +0 -129
  108. data/lib/protocols/httpcli2.rb +0 -803
  109. data/lib/protocols/httpclient.rb +0 -270
  110. data/lib/protocols/linetext2.rb +0 -161
  111. data/lib/protocols/postgres.rb +0 -261
  112. data/lib/protocols/saslauth.rb +0 -179
  113. data/lib/protocols/smtpclient.rb +0 -308
  114. data/lib/protocols/smtpserver.rb +0 -556
  115. data/lib/protocols/stomp.rb +0 -153
  116. data/tests/test_eventables.rb +0 -77
@@ -0,0 +1,200 @@
1
+ #--
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 15 November 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
+ module Protocols
29
+
30
+ # Implements Stomp (http://docs.codehaus.org/display/STOMP/Protocol).
31
+ #
32
+ # == Usage example
33
+ #
34
+ # module StompClient
35
+ # include EM::Protocols::Stomp
36
+ #
37
+ # def connection_completed
38
+ # connect :login => 'guest', :passcode => 'guest'
39
+ # end
40
+ #
41
+ # def receive_msg msg
42
+ # if msg.command == "CONNECTED"
43
+ # subscribe '/some/topic'
44
+ # else
45
+ # p ['got a message', msg]
46
+ # puts msg.body
47
+ # end
48
+ # end
49
+ # end
50
+ #
51
+ # EM.run{
52
+ # EM.connect 'localhost', 61613, StompClient
53
+ # }
54
+ #
55
+ module Stomp
56
+ include LineText2
57
+
58
+ class Message
59
+ # The command associated with the message, usually 'CONNECTED' or 'MESSAGE'
60
+ attr_accessor :command
61
+ # Hash containing headers such as destination and message-id
62
+ attr_accessor :header
63
+ alias :headers :header
64
+ # Body of the message
65
+ attr_accessor :body
66
+
67
+ def initialize # :nodoc:
68
+ @header = {}
69
+ @state = :precommand
70
+ @content_length = nil
71
+ end
72
+ def consume_line line # :nodoc:
73
+ if @state == :precommand
74
+ unless line =~ /\A\s*\Z/
75
+ @command = line
76
+ @state = :headers
77
+ end
78
+ elsif @state == :headers
79
+ if line == ""
80
+ if @content_length
81
+ yield( [:sized_text, @content_length+1] )
82
+ else
83
+ @state = :body
84
+ yield( [:unsized_text] )
85
+ end
86
+ elsif line =~ /\A([^:]+):(.+)\Z/
87
+ k = $1.dup.strip
88
+ v = $2.dup.strip
89
+ @header[k] = v
90
+ if k == "content-length"
91
+ @content_length = v.to_i
92
+ end
93
+ else
94
+ # This is a protocol error. How to signal it?
95
+ end
96
+ elsif @state == :body
97
+ @body = line
98
+ yield( [:dispatch] )
99
+ end
100
+ end
101
+ end
102
+
103
+ # :stopdoc:
104
+
105
+ def send_frame verb, headers={}, body=""
106
+ ary = [verb, "\n"]
107
+ headers.each {|k,v| ary << "#{k}:#{v}\n" }
108
+ ary << "content-length: #{body.to_s.length}\n"
109
+ ary << "content-type: text/plain; charset=UTF-8\n"
110
+ ary << "\n"
111
+ ary << body.to_s
112
+ ary << "\0"
113
+ send_data ary.join
114
+ end
115
+
116
+ def receive_line line
117
+ @stomp_initialized || init_message_reader
118
+ @stomp_message.consume_line(line) {|outcome|
119
+ if outcome.first == :sized_text
120
+ set_text_mode outcome[1]
121
+ elsif outcome.first == :unsized_text
122
+ set_delimiter "\0"
123
+ elsif outcome.first == :dispatch
124
+ receive_msg(@stomp_message) if respond_to?(:receive_msg)
125
+ init_message_reader
126
+ end
127
+ }
128
+ end
129
+
130
+ def receive_binary_data data
131
+ @stomp_message.body = data[0..-2]
132
+ receive_msg(@stomp_message) if respond_to?(:receive_msg)
133
+ init_message_reader
134
+ end
135
+
136
+ def init_message_reader
137
+ @stomp_initialized = true
138
+ set_delimiter "\n"
139
+ set_line_mode
140
+ @stomp_message = Message.new
141
+ end
142
+
143
+ # :startdoc:
144
+
145
+ # Invoked with an incoming Stomp::Message received from the STOMP server
146
+ def receive_msg msg
147
+ # stub, overwrite this in your handler
148
+ end
149
+
150
+ # CONNECT command, for authentication
151
+ #
152
+ # connect :login => 'guest', :passcode => 'guest'
153
+ #
154
+ def connect parms={}
155
+ send_frame "CONNECT", parms
156
+ end
157
+
158
+ # SEND command, for publishing messages to a topic
159
+ #
160
+ # send '/topic/name', 'some message here'
161
+ #
162
+ def send destination, body, parms={}
163
+ send_frame "SEND", parms.merge( :destination=>destination ), body.to_s
164
+ end
165
+
166
+ # SUBSCRIBE command, for subscribing to topics
167
+ #
168
+ # subscribe '/topic/name', false
169
+ #
170
+ def subscribe dest, ack=false
171
+ send_frame "SUBSCRIBE", {:destination=>dest, :ack=>(ack ? "client" : "auto")}
172
+ end
173
+
174
+ # ACK command, for acknowledging receipt of messages
175
+ #
176
+ # module StompClient
177
+ # include EM::P::Stomp
178
+ #
179
+ # def connection_completed
180
+ # connect :login => 'guest', :passcode => 'guest'
181
+ # # subscribe with ack mode
182
+ # subscribe '/some/topic', true
183
+ # end
184
+ #
185
+ # def receive_msg msg
186
+ # if msg.command == "MESSAGE"
187
+ # ack msg.headers['message-id']
188
+ # puts msg.body
189
+ # end
190
+ # end
191
+ # end
192
+ #
193
+ def ack msgid
194
+ send_frame "ACK", 'message-id'=> msgid
195
+ end
196
+
197
+ end
198
+ end
199
+ end
200
+
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ #--
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -24,34 +24,30 @@
24
24
  #
25
25
  #
26
26
 
27
-
28
-
29
27
  module EventMachine
30
- module Protocols
28
+ module Protocols
31
29
 
32
- class TcpConnectTester < Connection
33
- include EventMachine::Deferrable
30
+ class TcpConnectTester < Connection # :nodoc:
31
+ include EventMachine::Deferrable
34
32
 
35
- def self.test( host, port )
36
- EventMachine.connect( host, port, self )
37
- end
33
+ def self.test( host, port )
34
+ EventMachine.connect( host, port, self )
35
+ end
38
36
 
39
- def post_init
40
- @start_time = Time.now
41
- end
37
+ def post_init
38
+ @start_time = Time.now
39
+ end
42
40
 
43
- def connection_completed
44
- @completed = true
45
- set_deferred_status :succeeded, (Time.now - @start_time)
46
- close_connection
47
- end
48
-
49
- def unbind
50
- set_deferred_status :failed, (Time.now - @start_time) unless @completed
51
- end
52
- end
41
+ def connection_completed
42
+ @completed = true
43
+ set_deferred_status :succeeded, (Time.now - @start_time)
44
+ close_connection
45
+ end
53
46
 
47
+ def unbind
48
+ set_deferred_status :failed, (Time.now - @start_time) unless @completed
49
+ end
50
+ end
54
51
 
55
- end
56
- end
57
-
52
+ end
53
+ end
@@ -0,0 +1,61 @@
1
+ module EventMachine
2
+ # A cross thread, reactor scheduled, linear queue.
3
+ #
4
+ # This class provides a simple "Queue" like abstraction on top of the reactor
5
+ # scheduler. It services two primary purposes:
6
+ # * API sugar for stateful protocols
7
+ # * Pushing processing onto the same thread as the reactor
8
+ #
9
+ # See examples/ex_queue.rb for a detailed example.
10
+ #
11
+ # q = EM::Queue.new
12
+ # q.push('one', 'two', 'three')
13
+ # 3.times do
14
+ # q.pop{ |msg| puts(msg) }
15
+ # end
16
+ #
17
+ class Queue
18
+ # Create a new queue
19
+ def initialize
20
+ @items = []
21
+ @popq = []
22
+ end
23
+
24
+ # Pop items off the queue, running the block on the reactor thread. The pop
25
+ # will not happen immediately, but at some point in the future, either in
26
+ # the next tick, if the queue has data, or when the queue is populated.
27
+ def pop(*a, &b)
28
+ cb = EM::Callback(*a, &b)
29
+ EM.schedule do
30
+ if @items.empty?
31
+ @popq << cb
32
+ else
33
+ cb.call @items.shift
34
+ end
35
+ end
36
+ nil # Always returns nil
37
+ end
38
+
39
+ # Push items onto the queue in the reactor thread. The items will not appear
40
+ # in the queue immediately, but will be scheduled for addition during the
41
+ # next reactor tick.
42
+ def push(*items)
43
+ EM.schedule do
44
+ @items.concat items
45
+ @popq.shift.call @items.shift until @items.empty? || @popq.empty?
46
+ end
47
+ end
48
+
49
+ # N.B. This is a peek, it's not thread safe, and may only tend toward
50
+ # accuracy.
51
+ def empty?
52
+ @items.empty?
53
+ end
54
+
55
+ # N.B. This is a peek, it's not thread safe, and may only tend toward
56
+ # accuracy.
57
+ def size
58
+ @items.size
59
+ end
60
+ end
61
+ end
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ #--
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -21,68 +21,65 @@
21
21
  #
22
22
  #---------------------------------------------------------------------------
23
23
  #
24
- #
25
-
26
-
27
- # Support for Erlang-style processes.
28
24
  #
29
25
 
30
-
31
26
  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
27
+ # Support for Erlang-style processes.
28
+ #
29
+ class SpawnedProcess
30
+ # Send a message to the spawned process
31
+ def notify *x
32
+ me = self
33
+ EM.next_tick {
34
+ # A notification executes in the context of this
35
+ # SpawnedProcess object. That makes self and notify
36
+ # work as one would expect.
37
+ #
38
+ y = me.call(*x)
39
+ if y and y.respond_to?(:pull_out_yield_block)
40
+ a,b = y.pull_out_yield_block
41
+ set_receiver a
42
+ self.notify if b
43
+ end
44
+ }
45
+ end
46
+ alias_method :resume, :notify
47
+ alias_method :run, :notify # for formulations like (EM.spawn {xxx}).run
48
+ #attr_accessor :receiver
51
49
 
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
50
+ #--
51
+ # I know I'm missing something stupid, but the inside of class << s
52
+ # can't see locally-bound values. It can see globals, though.
53
+ def set_receiver blk
54
+ $em______tmpglobal = blk
55
+ class << self
56
+ define_method :call, $em______tmpglobal.dup
57
+ end
58
+ end
60
59
 
61
- end
60
+ end
62
61
 
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
62
+ class YieldBlockFromSpawnedProcess # :nodoc:
63
+ def initialize block, notify
64
+ @block = [block,notify]
65
+ end
66
+ def pull_out_yield_block
67
+ @block
68
+ end
69
+ end
71
70
 
72
- def EventMachine.spawn &block
73
- s = SpawnedProcess.new
74
- s.set_receiver block
75
- s
76
- end
71
+ # Spawn an erlang-style process
72
+ def self.spawn &block
73
+ s = SpawnedProcess.new
74
+ s.set_receiver block
75
+ s
76
+ end
77
77
 
78
- def EventMachine.yield &block
79
- return YieldBlockFromSpawnedProcess.new( block, false )
80
- end
78
+ def self.yield &block # :nodoc:
79
+ return YieldBlockFromSpawnedProcess.new( block, false )
80
+ end
81
81
 
82
- def EventMachine.yield_and_notify &block
83
- return YieldBlockFromSpawnedProcess.new( block, true )
84
- end
82
+ def self.yield_and_notify &block # :nodoc:
83
+ return YieldBlockFromSpawnedProcess.new( block, true )
84
+ end
85
85
  end
86
-
87
-
88
-
@@ -1,4 +1,4 @@
1
- # $Id$
1
+ #--
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -25,88 +25,106 @@
25
25
 
26
26
 
27
27
  module EventMachine
28
- class FileStreamer
29
- MappingThreshold = 16384
30
- BackpressureLevel = 50000
31
- ChunkSize = 16384
28
+ class FileStreamer
29
+ include Deferrable
32
30
 
33
- include Deferrable
34
- def initialize connection, filename, args
35
- @connection = connection
36
- @http_chunks = args[:http_chunks]
31
+ # Use mapped streamer for files bigger than 16k
32
+ MappingThreshold = 16384
33
+ # Wait until next tick to send more data when 50k is still in the outgoing buffer
34
+ BackpressureLevel = 50000
35
+ # Send 16k chunks at a time
36
+ ChunkSize = 16384
37
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
38
+ # Stream a file over a given connection. An optional :http_chunks => true argument will
39
+ # use HTTP 1.1 style chunked-encoding semantics.
40
+ #
41
+ # module FileSender
42
+ # def post_init
43
+ # streamer = EventMachine::FileStreamer.new(self, '/tmp/bigfile.tar')
44
+ # streamer.callback{
45
+ # # file was sent successfully
46
+ # close_connection_after_writing
47
+ # }
48
+ # end
49
+ # end
50
+ #
51
+ def initialize connection, filename, args = {}
52
+ @connection = connection
53
+ @http_chunks = args[:http_chunks]
49
54
 
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
55
+ if File.exist?(filename)
56
+ @size = File.size?(filename)
57
+ if @size <= MappingThreshold
58
+ stream_without_mapping filename
59
+ else
60
+ stream_with_mapping filename
61
+ end
62
+ else
63
+ fail "file not found"
64
+ end
65
+ end
61
66
 
62
- def stream_with_mapping filename
63
- ensure_mapping_extension_is_present
67
+ def stream_without_mapping filename # :nodoc:
68
+ if @http_chunks
69
+ @connection.send_data "#{@size.to_s(16)}\r\n"
70
+ @connection.send_file_data filename
71
+ @connection.send_data "\r\n0\r\n\r\n"
72
+ else
73
+ @connection.send_file_data filename
74
+ end
75
+ succeed
76
+ end
77
+ private :stream_without_mapping
64
78
 
65
- @position = 0
66
- @mapping = EventMachine::FastFileReader::Mapper.new filename
67
- stream_one_chunk
68
- end
69
- private :stream_with_mapping
79
+ def stream_with_mapping filename # :nodoc:
80
+ ensure_mapping_extension_is_present
70
81
 
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)
82
+ @position = 0
83
+ @mapping = EventMachine::FastFileReader::Mapper.new filename
84
+ stream_one_chunk
85
+ end
86
+ private :stream_with_mapping
80
87
 
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
88
+ # Used internally to stream one chunk at a time over multiple reactor ticks
89
+ def stream_one_chunk
90
+ loop {
91
+ if @position < @size
92
+ if @connection.get_outbound_data_size > BackpressureLevel
93
+ EventMachine::next_tick {stream_one_chunk}
94
+ break
95
+ else
96
+ len = @size - @position
97
+ len = ChunkSize if (len > ChunkSize)
84
98
 
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
99
+ @connection.send_data( "#{len.to_s(16)}\r\n" ) if @http_chunks
100
+ @connection.send_data( @mapping.get_chunk( @position, len ))
101
+ @connection.send_data("\r\n") if @http_chunks
95
102
 
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
103
+ @position += len
104
+ end
105
+ else
106
+ @connection.send_data "0\r\n\r\n" if @http_chunks
107
+ @mapping.close
108
+ succeed
109
+ break
110
+ end
111
+ }
112
+ end
109
113
 
110
- end
114
+ #--
115
+ # We use an outboard extension class to get memory-mapped files.
116
+ # It's outboard to avoid polluting the core distro, but that means
117
+ # there's a "hidden" dependency on it. The first time we get here in
118
+ # any run, try to load up the dependency extension. User code will see
119
+ # a LoadError if it's not available, but code that doesn't require
120
+ # mapped files will work fine without it. This is a somewhat difficult
121
+ # compromise between usability and proper modularization.
122
+ #
123
+ def ensure_mapping_extension_is_present # :nodoc:
124
+ @@fastfilereader ||= (require 'fastfilereaderext')
125
+ end
126
+ private :ensure_mapping_extension_is_present
127
+
128
+ end
111
129
  end
112
130