Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|
lib/codin_rep/communication.rb | 124 | 124 | 0.00%
|
0.00%
|
Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.
2 # -*- coding: utf-8 -*- |
3 # codin_rep - Gem para acesso de REPs da Telebyte |
4 # Copyright (C) 2016 O.S. Systems Softwares Ltda. |
5 |
6 # This program is free software: you can redistribute it and/or modify |
7 # it under the terms of the GNU Affero General Public License as |
8 # published by the Free Software Foundation, either version 3 of the |
9 # License, or (at your option) any later version. |
10 |
11 # This program is distributed in the hope that it will be useful, |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 # GNU Affero General Public License for more details. |
15 |
16 # You should have received a copy of the GNU Affero General Public License |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 |
19 # Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil. |
20 # e-mail: contato@ossystems.com.br |
21 |
22 require 'socket' |
23 require 'timeout' |
24 |
25 module CodinRep |
26 class Communication |
27 READ_SIZE = 4096 |
28 |
29 include Timeout |
30 |
31 def self.finalize(socket) |
32 proc { socket.close } |
33 end |
34 |
35 def initialize(host_address, port, timeout_time=60, max_attempts=3) |
36 @host_address = host_address |
37 @port = port |
38 @timeout_time = timeout_time |
39 @max_attempts = max_attempts |
40 @socket = nil |
41 end |
42 |
43 def open_socket |
44 if @socket |
45 @socket.close |
46 @socket = nil |
47 end |
48 |
49 @attempt = 0 |
50 while @attempt < @max_attempts do |
51 begin |
52 timeout(@timeout_time) { |
53 @socket = TCPSocket.open(@host_address, @port) |
54 } |
55 # Use a finalizer to close the socket if "self" is going to be |
56 # destroyed. |
57 ObjectSpace.define_finalizer( self, self.class.finalize(@socket) ) |
58 rescue Timeout::Error |
59 @socket = nil |
60 end |
61 break if @socket |
62 |
63 @attempt += 1 |
64 end |
65 |
66 raise "Timeout error" if @attempt >= @max_attempts |
67 @socket |
68 end |
69 |
70 def communicate(payload, expected_response_size) |
71 open_socket if @socket.nil? |
72 |
73 @payload = payload |
74 @expected_response_size = expected_response_size |
75 |
76 while @attempt < @max_attempts do |
77 @received_data = nil |
78 |
79 @received_data = send_receive_data(@payload) |
80 |
81 break unless @received_data.nil? |
82 @attempt += 1 |
83 end |
84 |
85 raise "Timeout error" if @attempt >= @max_attempts |
86 @received_data |
87 end |
88 |
89 def close |
90 if @socket |
91 @socket.close |
92 @socket = nil |
93 end |
94 end |
95 |
96 private |
97 |
98 def send_receive_data(data_to_send) |
99 @socket.write(data_to_send) |
100 @socket.flush |
101 data_to_receive = "" |
102 |
103 # expected_response_size can be a Fixnum, for fixed responses sizes, or |
104 # a proc, where the response size comes inside the response itself. |
105 if @expected_response_size.is_a?(Proc) |
106 expected_size = @expected_response_size.call(data_to_receive) |
107 else |
108 expected_size = @expected_response_size |
109 end |
110 |
111 while data_to_receive.size < expected_size |
112 bytes_to_be_read = expected_size - data_to_receive.size |
113 bytes_to_be_read = READ_SIZE if bytes_to_be_read > READ_SIZE |
114 |
115 timeout(@timeout_time) { |
116 data_to_receive += @socket.readpartial( bytes_to_be_read ) |
117 } |
118 if @expected_response_size.is_a?(Proc) |
119 expected_size = @expected_response_size.call(data_to_receive) |
120 end |
121 end |
122 data_to_receive |
123 end |
124 end |
125 end |
Generated on 2017-01-31 16:03:32 -0200 with SimpleCov-RCov 0.2.3