class Thrift::Socket
Attributes
Public Class Methods
Source
# File lib/thrift/transport/socket.rb 26 def initialize(host = "localhost", port = 9090, timeout = nil) 27 @host = host 28 @port = port 29 @timeout = timeout 30 @desc = "#{host}:#{port}" 31 @handle = nil 32 end
Public Instance Methods
Source
# File lib/thrift/transport/socket.rb 108 def close 109 close_socket(@handle) 110 @handle = nil 111 end
Source
# File lib/thrift/transport/socket.rb 36 def open 37 raise TransportException.new(TransportException::ALREADY_OPEN, "Socket already open") if open? 38 39 deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + @timeout unless @timeout.nil? || @timeout == 0 40 @handle = connect_socket(deadline) 41 end
Source
# File lib/thrift/transport/socket.rb 43 def open? 44 !@handle.nil? && !@handle.closed? 45 end
Source
# File lib/thrift/transport/socket.rb 78 def read(sz) 79 raise TransportException.new(TransportException::NOT_OPEN, "closed stream") unless open? 80 81 begin 82 if @timeout.nil? || @timeout == 0 83 data = @handle.readpartial(sz) 84 else 85 deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + @timeout 86 87 data = loop do 88 break @handle.read_nonblock(sz) 89 rescue IO::WaitReadable 90 wait_for(:read, deadline, sz) 91 rescue IO::WaitWritable 92 wait_for(:write, deadline, sz) 93 end 94 end 95 rescue TransportException 96 close 97 raise 98 rescue StandardError => e 99 close 100 raise TransportException.new(TransportException::NOT_OPEN, e.message) 101 end 102 if data.nil? || data.length == 0 103 raise TransportException.new(TransportException::UNKNOWN, "Socket: Could not read #{sz} bytes from #{@desc}") 104 end 105 data 106 end
Source
# File lib/thrift/transport/socket.rb 113 def to_io 114 @handle&.to_io || raise(IOError, "closed stream") 115 end
Source
# File lib/thrift/transport/socket.rb 117 def to_s 118 "socket(#{@host}:#{@port})" 119 end
Source
# File lib/thrift/transport/socket.rb 47 def write(str) 48 raise TransportException.new(TransportException::NOT_OPEN, "closed stream") unless open? 49 str = Bytes.force_binary_encoding(str) 50 begin 51 if @timeout.nil? || @timeout == 0 52 @handle.write(str) 53 else 54 deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + @timeout 55 len = 0 56 57 while len < str.length 58 begin 59 len += @handle.write_nonblock(str[len..]) 60 rescue IO::WaitWritable 61 wait_for(:write, deadline, str.length) 62 rescue IO::WaitReadable 63 wait_for(:read, deadline, str.length) 64 end 65 end 66 67 len 68 end 69 rescue TransportException 70 close 71 raise 72 rescue StandardError => e 73 close 74 raise TransportException.new(TransportException::NOT_OPEN, e.message) 75 end 76 end
Private Instance Methods
Source
# File lib/thrift/transport/socket.rb 172 def close_socket(socket) 173 return if socket.nil? 174 return if socket.respond_to?(:closed?) && socket.closed? 175 176 socket.close 177 rescue StandardError 178 nil 179 end
Source
# File lib/thrift/transport/socket.rb 123 def connect_socket(deadline) 124 last_error = nil 125 connected_socket = nil 126 127 Addrinfo.foreach(@host, @port, nil, :STREAM) do |addrinfo| 128 socket = nil 129 130 begin 131 socket = if deadline 132 remaining = deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC) 133 raise TransportException.new(TransportException::TIMED_OUT, "Socket: Timed out opening connection to #{@desc}") if remaining <= 0 134 135 addrinfo.connect(timeout: remaining) 136 else 137 addrinfo.connect 138 end 139 140 socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1) 141 connected_socket = socket 142 break 143 rescue Errno::ETIMEDOUT => e 144 close_socket(socket) 145 last_error = e 146 rescue TransportException 147 close_socket(socket) 148 raise 149 rescue StandardError => e 150 close_socket(socket) 151 last_error = e 152 end 153 end 154 155 return connected_socket if connected_socket 156 157 if last_error.is_a?(Errno::ETIMEDOUT) 158 raise TransportException.new(TransportException::TIMED_OUT, "Socket: Timed out opening connection to #{@desc}") 159 end 160 161 if deadline && deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC) <= 0 162 raise TransportException.new(TransportException::TIMED_OUT, "Socket: Timed out opening connection to #{@desc}") 163 end 164 165 raise TransportException.new(TransportException::NOT_OPEN, "Could not connect to #{@desc}"), cause: last_error 166 rescue TransportException 167 raise 168 rescue StandardError 169 raise TransportException.new(TransportException::NOT_OPEN, "Could not connect to #{@desc}") 170 end
Source
# File lib/thrift/transport/socket.rb 181 def wait_for(operation, deadline, sz) 182 rd_ary, wr_ary = case operation 183 when :read 184 [[@handle], nil] 185 when :write 186 [nil, [@handle]] 187 else 188 raise ArgumentError, "Unknown IO wait operation: #{operation.inspect}" 189 end 190 191 loop do 192 remaining = deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC) 193 if remaining <= 0 194 case operation 195 when :read 196 raise TransportException.new(TransportException::TIMED_OUT, "Socket: Timed out reading #{sz} bytes from #{@desc}") 197 when :write 198 raise TransportException.new(TransportException::TIMED_OUT, "Socket: Timed out writing #{sz} bytes to #{@desc}") 199 end 200 end 201 202 rd, wr, = IO.select(rd_ary, wr_ary, nil, remaining) 203 return if (rd && !rd.empty?) || (wr && !wr.empty?) 204 end 205 end