Class: EventMachine::FileStreamer
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Instance Chain:
self,
Deferrable
|
|
| Inherits: | Object |
| Defined in: | lib/em/streamer.rb |
Overview
Streams a file over a given connection. Streaming begins once the object is instantiated. Typically FileStreamer instances are not reused.
Streaming uses buffering for files larger than 16K and uses so-called fast file reader (a C++ extension) if available (it is part of eventmachine gem itself).
Constant Summary
-
BackpressureLevel =
# File 'lib/em/streamer.rb', line 28
Wait until next tick to send more data when 50k is still in the outgoing buffer
50000 -
ChunkSize =
# File 'lib/em/streamer.rb', line 30
Send 16k chunks at a time
16384 -
MappingThreshold =
# File 'lib/em/streamer.rb', line 26
Use mapped streamer for files bigger than 16k
16384
Deferrable - Included
Class Method Summary
Instance Method Summary
-
#stream_one_chunk
Internal use only
Internal use only
Used internally to stream one chunk at a time over multiple reactor ticks.
-
#ensure_mapping_extension_is_present
private
Internal use only
Internal use only
We use an outboard extension class to get memory-mapped files.
- #stream_with_mapping(filename) private Internal use only Internal use only
- #stream_without_mapping(filename) private Internal use only Internal use only
Deferrable - Included
| #callback | Specify a block to be executed if and when the |
| #cancel_callback | Cancels an outstanding callback to &block if any. |
| #cancel_errback | Cancels an outstanding errback to &block if any. |
| #cancel_timeout | Cancels an outstanding timeout if any. |
| #errback | Specify a block to be executed if and when the |
| #fail | Sugar for set_deferred_status(:failed, ...). |
| #set_deferred_failure | Alias for Deferrable#fail. |
| #set_deferred_status | Sets the "disposition" (status) of the |
| #set_deferred_success | Alias for Deferrable#succeed. |
| #succeed | Sugar for set_deferred_status(:succeeded, ...). |
| #timeout | Setting a timeout on a |
Constructor Details
.new(connection, filename, args = {}) ⇒ FileStreamer
# File 'lib/em/streamer.rb', line 36
def initialize connection, filename, args = {} @connection = connection @http_chunks = args[:http_chunks] if File.exist?(filename) @size = File.size(filename) if @size <= MappingThreshold stream_without_mapping filename else stream_with_mapping filename end else fail "file not found" end end
Instance Method Details
#ensure_mapping_extension_is_present (private)
We use an outboard extension class to get memory-mapped files. It's outboard to avoid polluting the core distro, but that means there's a "hidden" dependency on it. The first time we get here in any run, try to load up the dependency extension. User code will see a LoadError if it's not available, but code that doesn't require mapped files will work fine without it. This is a somewhat difficult compromise between usability and proper modularization.
# File 'lib/em/streamer.rb', line 112
def ensure_mapping_extension_is_present @@fastfilereader ||= (require 'fastfilereaderext') end
#stream_one_chunk
Used internally to stream one chunk at a time over multiple reactor ticks
# File 'lib/em/streamer.rb', line 77
def stream_one_chunk loop { if @position < @size if @connection.get_outbound_data_size > BackpressureLevel EventMachine::next_tick {stream_one_chunk} break else len = @size - @position len = ChunkSize if (len > ChunkSize) @connection.send_data( "#{len.to_s(16)}\r\n" ) if @http_chunks @connection.send_data( @mapping.get_chunk( @position, len )) @connection.send_data("\r\n") if @http_chunks @position += len end else @connection.send_data "0\r\n\r\n" if @http_chunks @mapping.close succeed break end } end
#stream_with_mapping(filename) (private)
# File 'lib/em/streamer.rb', line 66
def stream_with_mapping filename ensure_mapping_extension_is_present @position = 0 @mapping = EventMachine::FastFileReader::Mapper.new filename stream_one_chunk end
#stream_without_mapping(filename) (private)
# File 'lib/em/streamer.rb', line 53
def stream_without_mapping filename if @http_chunks @connection.send_data "#{@size.to_s(16)}\r\n" @connection.send_file_data filename @connection.send_data "\r\n0\r\n\r\n" else @connection.send_file_data filename end succeed end