em-ruby-sockets 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []