lib/aerospike/socket/base.rb in aerospike-2.7.0 vs lib/aerospike/socket/base.rb in aerospike-2.8.0
- old
+ new
@@ -33,20 +33,12 @@
bytes_read += result.bytesize
end
end
def read_from_socket(length)
- begin
+ with_timeout(@timeout) do
read_nonblock(length)
- rescue ::IO::WaitReadable => e
- if ::IO::select([self], nil, nil, @timeout)
- retry
- else
- raise ::Aerospike::Exceptions::Connection.new("#{e}")
- end
- rescue => e
- raise ::Aerospike::Exceptions::Connection.new("#{e}")
end
end
def write(buffer, length)
bytes_written = 0
@@ -54,20 +46,12 @@
bytes_written += write_to_socket(buffer.read(bytes_written, length - bytes_written))
end
end
def write_to_socket(data)
- begin
+ with_timeout(@timeout) do
write_nonblock(data)
- rescue ::IO::WaitWritable => e
- if ::IO::select(nil, [self], nil, @timeout)
- retry
- else
- raise ::Aerospike::Exceptions::Connection.new("#{e}")
- end
- rescue => e
- raise ::Aerospike::Exceptions::Connection.new("#{e}")
end
end
def timeout=(timeout)
@timeout = timeout && timeout > 0 ? timeout : nil
@@ -75,12 +59,55 @@
def connected?
!closed?
end
+ # Returns whether the connection to the server is alive.
+ #
+ # It is useful to call this method before making a call to the server
+ # that would change data on the server.
+ #
+ # Note: This method is only useful if the server closed the connection or
+ # if a previous connection failure occurred. If the server is hard killed
+ # this will still return true until one or more writes are attempted.
+ def alive?
+ return false if closed?
+
+ if IO.select([self], nil, nil, 0)
+ !eof? rescue false
+ else
+ true
+ end
+ rescue IOError
+ false
+ end
+
def close
return if closed?
super()
+ end
+
+ private
+
+ # Note: For SSL connections, read_nonblock may invoke write system call,
+ # which may raise IO::WaitWritable, and vice versa, due to SSL
+ # renegotiation, so we should always rescue both.
+ def with_timeout(timeout, &block)
+ block.call
+ rescue IO::WaitReadable => e
+ if IO::select([self], nil, nil, timeout)
+ retry
+ else
+ fail Aerospike::Exceptions::Connection, "Socket timeout: #{e}"
+ end
+ rescue IO::WaitWritable => e
+ if IO::select(nil, [self], nil, timeout)
+ retry
+ else
+ fail Aerospike::Exceptions::Connection, "Socket timeout: #{e}"
+ end
+ rescue => e
+ raise Aerospike::Exceptions::Connection, "Socket error: #{e}"
end
end
end
end
\ No newline at end of file