]> git.saurik.com Git - redis.git/blobdiff - client-libraries/ruby/lib/server.rb
minor fix for Solaris boxes
[redis.git] / client-libraries / ruby / lib / server.rb
index c5ac808c077b3d91ae353bfaac257b0ccd5eb095..4fb54937fb1d7cbecb7926e78b9e76de1e95956b 100644 (file)
@@ -24,12 +24,6 @@ end
 
 class Server
 
-  ##
-  # The amount of time to wait before attempting to re-establish a
-  # connection with a server that is marked dead.
-
-  RETRY_DELAY = 30.0
-
   ##
   # The host the redis server is running on.
 
@@ -40,16 +34,6 @@ class Server
 
   attr_reader :port
   
-  ##
-  #
-  
-  attr_reader :replica
-
-  ##
-  # The time of next retry if the connection is dead.
-
-  attr_reader :retry
-
   ##
   # A text status string describing the state of the server.
 
@@ -67,7 +51,6 @@ class Server
     @port   = port.to_i
 
     @sock   = nil
-    @retry  = nil
     @status = 'NOT CONNECTED'
     @timeout = timeout
   end
@@ -83,38 +66,31 @@ class Server
   # Returns the connected socket object on success or nil on failure.
 
   def socket
-    return @sock if @sock and not @sock.closed?
-
-    @sock = nil
-
-    # If the host was dead, don't retry for a while.
-    return if @retry and @retry > Time.now
-
+    return @sock if socket_alive?
+    close
     # Attempt to connect if not already connected.
     begin
       @sock = connect_to(@host, @port, @timeout)
       @sock.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
-      @retry  = nil
       @status = 'CONNECTED'
     rescue Errno::EPIPE, Errno::ECONNREFUSED => e
-      puts "Socket died... socket: #{@sock.inspect}\n" if $debug
-      @sock.close
+      puts "Socket died... : #{e}\n" if $debug
       retry
     rescue SocketError, SystemCallError, IOError => err
       puts "Unable to open socket: #{err.class.name}, #{err.message}" if $debug
-      mark_dead err
     end
     @sock
   end
 
   def connect_to(host, port, timeout=nil)
-    socket = TCPSocket.new(host, port, 0)
+    socket = TCPSocket.new(host, port)
+    socket.set_encoding(Encoding::BINARY) if socket.respond_to?(:set_encoding)
     if timeout
       socket.instance_eval <<-EOR
-        alias :blocking_gets :gets
-        def gets(*args)
+        alias :blocking_readline :readline
+        def readline(*args)
           RedisTimer.timeout(#{timeout}) do
-            self.blocking_gets(*args)
+            self.blocking_readline(*args)
           end
         end
         alias :blocking_read :read
@@ -134,27 +110,22 @@ class Server
     socket
   end
 
-  ##
   # Close the connection to the redis server targeted by this
-  # object.  The server is not considered dead.
+  # object. 
 
   def close
-    @sock.close if @sock && !@sock.closed?
+    @sock.close if !@sock.nil? && !@sock.closed?
     @sock   = nil
-    @retry  = nil
     @status = "NOT CONNECTED"
   end
 
-  ##
-  # Mark the server as dead and close its socket.
-  def mark_dead(error)
-    @sock.close if @sock && !@sock.closed?
-    @sock   = nil
-    @retry  = Time.now #+ RETRY_DELAY
-
-    reason = "#{error.class.name}: #{error.message}"
-    @status = sprintf "%s:%s DEAD (%s), will retry at %s", @host, @port, reason, @retry
-    puts @status
-  end
-
+  private
+    def socket_alive?
+      #BTM - TODO - FileStat is borked under JRuby
+      unless defined?(JRUBY_VERSION)
+        !@sock.nil? &&  !@sock.closed? && @sock.stat.readable?
+      else 
+        !@sock.nil? &&  !@sock.closed?
+      end
+    end
 end