em-ruby-sockets 0.0.1 → 0.0.2

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.
@@ -0,0 +1,127 @@
1
+ module EventMachine::RubySockets
2
+
3
+ # Streams a file over a given TCP connection.
4
+ # It makes use of the fastfilereaderext.so Ruby extension.
5
+ #
6
+ # class MyFileStreamer < EM::RubySockets::TcpClient
7
+ # def post_init
8
+ # streamer = EM::RubySockets::FileStreamer.new(self, "/tmp/bigfile.tar.gz")
9
+ # streamer.callback {
10
+ # # file was sent successfully
11
+ # disconnect
12
+ # }
13
+ # streamer.errback {
14
+ # # file could not be sent
15
+ # disconnect
16
+ # }
17
+ # streamer.run
18
+ # end
19
+ # end
20
+ #
21
+ class FileStreamer
22
+ # Wait until next tick to send more data when 50k is still in the outgoing buffer.
23
+ BackpressureLevel = 50000
24
+ # Send 16k chunks at a time.
25
+ ChunkSize = 16384
26
+
27
+ # Parameters:
28
+ #
29
+ # - [connection] An EventMachine::RubySockets::TcpClient, EventMachine::RubySockets::TcpServer, EventMachine::RubySockets::TlsClient or EventMachine::RubySockets::TlsServer.
30
+ # - [filename] File path.
31
+ # - [args] A Hash with options.
32
+ #
33
+ # Valid options for _args_:
34
+ #
35
+ # - [http_chunks] Use HTTP 1.1 chunked-encoding.
36
+ #
37
+ def initialize connection, filename, args = {}
38
+ @connection = connection
39
+ @filename = filename
40
+ @http_chunks = args[:http_chunks]
41
+ end
42
+
43
+ # Set the success callback to be executed upon file transfer completion.
44
+ def callback &block
45
+ @on_success_block = block
46
+ end
47
+
48
+ # Set the error callback (errback) to be executed if file transfer fails. The errback
49
+ # is called by passing a single argument which can be _:invalid_file_ or _:disconnected_.
50
+ def errback &block
51
+ @on_error_block = block
52
+ end
53
+
54
+ # Start sending the file. This method must be called after setting both the callback and
55
+ # errback blocks.
56
+ def run
57
+ unless ::File.readable?(@filename) and ::File.file?(@filename)
58
+ do_error :invalid_file
59
+ return false
60
+ end
61
+
62
+ @size = ::File.size(@filename)
63
+ stream_with_mapping
64
+ true
65
+ end
66
+
67
+ # Returns a Float value indicating the file percentage trasferred at this moment.
68
+ def percentage_sent
69
+ @mapping ? (@position.to_f / @size)*100 : 0.0
70
+ end
71
+
72
+
73
+ private
74
+
75
+ def do_success
76
+ @on_success_block && @on_success_block.call
77
+ end
78
+
79
+ def do_error cause
80
+ @on_error_block && @on_error_block.call(cause)
81
+ end
82
+
83
+ def stream_with_mapping
84
+ ensure_mapping_extension_is_present
85
+
86
+ @position = 0
87
+ @mapping = ::EM::FastFileReader::Mapper.new @filename
88
+ stream_one_chunk
89
+ end
90
+
91
+ # Used internally to stream one chunk at a time over multiple reactor ticks.
92
+ def stream_one_chunk
93
+ loop do
94
+ if @connection.error?
95
+ @mapping.close
96
+ do_error :disconnected
97
+ break
98
+
99
+ elsif @position < @size
100
+ if @connection.get_outbound_data_size > BackpressureLevel
101
+ ::EM.next_tick { stream_one_chunk }
102
+ break
103
+ else
104
+ len = @size - @position
105
+ len = ChunkSize if (len > ChunkSize)
106
+
107
+ @connection.send_data "#{len.to_s(16)}\r\n" if @http_chunks
108
+ @connection.send_data @mapping.get_chunk(@position, len)
109
+ @connection.send_data "\r\n" if @http_chunks
110
+
111
+ @position += len
112
+ end
113
+ else
114
+ @connection.send_data "0\r\n\r\n" if @http_chunks
115
+ @mapping.close
116
+ do_success
117
+ break
118
+ end
119
+ end
120
+ end
121
+
122
+ def ensure_mapping_extension_is_present
123
+ @@fastfilereader ||= (require "fastfilereaderext")
124
+ end
125
+
126
+ end
127
+ end
@@ -1,5 +1,5 @@
1
1
  module EventMachine
2
2
  module RubySockets
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - "I\xC3\xB1aki Baz Castillo"
@@ -61,6 +61,7 @@ files:
61
61
  - lib/em-ruby-sockets/errors.rb
62
62
  - lib/em-ruby-sockets/tcp_connection.rb
63
63
  - lib/em-ruby-sockets/tcp_client.rb
64
+ - lib/em-ruby-sockets/file_streamer.rb
64
65
  has_rdoc: true
65
66
  homepage: https://github.com/ibc/em-ruby-sockets
66
67
  licenses: []