Class: Thrift::Socket

Inherits:
Transport show all
Defined in:
lib/thrift/transport/socket.rb

Direct Known Subclasses

UNIXSocket

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Transport

#flush, #read_all

Constructor Details

#initialize(host = 'localhost', port = 9090, timeout = nil) ⇒ Socket

Returns a new instance of Socket.



14
15
16
17
18
19
20
# File 'lib/thrift/transport/socket.rb', line 14

def initialize(host='localhost', port=9090, timeout=nil)
  @host = host
  @port = port
  @timeout = timeout
  @desc = "#{host}:#{port}"
  @handle = nil
end

Instance Attribute Details

#handleObject

Returns the value of attribute handle.



22
23
24
# File 'lib/thrift/transport/socket.rb', line 22

def handle
  @handle
end

#timeoutObject

Returns the value of attribute timeout.



22
23
24
# File 'lib/thrift/transport/socket.rb', line 22

def timeout
  @timeout
end

Instance Method Details

#closeObject



116
117
118
119
# File 'lib/thrift/transport/socket.rb', line 116

def close
  @handle.close unless @handle.nil? or @handle.closed?
  @handle = nil
end

#openObject



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/thrift/transport/socket.rb', line 24

def open
  begin
    addrinfo = ::Socket::getaddrinfo(@host, @port).first
    @handle = ::Socket.new(addrinfo[4], ::Socket::SOCK_STREAM, 0)
    sockaddr = ::Socket.sockaddr_in(addrinfo[1], addrinfo[3])
    begin
      @handle.connect_nonblock(sockaddr)
    rescue Errno::EINPROGRESS
      unless IO.select(nil, [ @handle ], nil, @timeout)
        raise TransportException.new(TransportException::NOT_OPEN, "Connection timeout to #{@desc}")
      end
      begin
        @handle.connect_nonblock(sockaddr)
      rescue Errno::EISCONN
      end
    end
    @handle
  rescue StandardError => e
    raise TransportException.new(TransportException::NOT_OPEN, "Could not connect to #{@desc}: #{e}")
  end
end

#open?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/thrift/transport/socket.rb', line 46

def open?
  !@handle.nil? and !@handle.closed?
end

#read(sz) ⇒ Object

Raises:

  • (IOError)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/thrift/transport/socket.rb', line 81

def read(sz)
  raise IOError, "closed stream" unless open?

  begin
    if @timeout.nil? or @timeout == 0
      data = @handle.readpartial(sz)
    else
      # it's possible to interrupt select for something other than the timeout
      # so we need to ensure we've waited long enough
      start = Time.now
      rd = nil # scoping
      loop do
        rd, = IO.select([@handle], nil, nil, @timeout)
        break if (rd and not rd.empty?) or Time.now - start >= @timeout
      end
      if rd.nil? or rd.empty?
        raise TransportException.new(TransportException::TIMED_OUT, "Socket: Timed out reading #{sz} bytes from #{@desc}")
      else
        data = @handle.readpartial(sz)
      end
    end
  rescue TransportException => e
    # don't let this get caught by the StandardError handler
    raise e
  rescue StandardError => e
    @handle.close unless @handle.closed?
    @handle = nil
    raise TransportException.new(TransportException::NOT_OPEN, e.message)
  end
  if (data.nil? or data.length == 0)
    raise TransportException.new(TransportException::UNKNOWN, "Socket: Could not read #{sz} bytes from #{@desc}")
  end
  data
end

#to_ioObject



121
122
123
# File 'lib/thrift/transport/socket.rb', line 121

def to_io
  @handle
end

#write(str) ⇒ Object

Raises:

  • (IOError)


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/thrift/transport/socket.rb', line 50

def write(str)
  raise IOError, "closed stream" unless open?
  begin
    if @timeout.nil? or @timeout == 0
      @handle.write(str)
    else
      len = 0
      start = Time.now
      while Time.now - start < @timeout
        rd, wr, = IO.select(nil, [@handle], nil, @timeout)
        if wr and not wr.empty?
          len += @handle.write_nonblock(str[len..-1])
          break if len >= str.length
        end
      end
      if len < str.length
        raise TransportException.new(TransportException::TIMED_OUT, "Socket: Timed out writing #{str.length} bytes to #{@desc}")
      else
        len
      end
    end
  rescue TransportException => e
    # pass this on
    raise e
  rescue StandardError => e
    @handle.close
    @handle = nil
    raise TransportException.new(TransportException::NOT_OPEN, e.message)
  end
end