lib/memcache/event_machine.rb in memcache-client-1.8.1 vs lib/memcache/event_machine.rb in memcache-client-1.8.2

- old
+ new

@@ -1,45 +1,65 @@ # Extensions for using memcache-client with EventMachine raise "memcache/event_machine requires Ruby 1.9" if RUBY_VERSION < '1.9' +require 'memcache' +require 'eventmachine' require 'fiber' -class MemCache::Server +class MemCache - alias :blocking_socket :socket - - def socket - # Support plain old TCP socket connections if the user - # has not setup EM. Much easier to deal with in irb, - # script/console, etc. - return blocking_socket if !EM.reactor_running? + # Since we are working in a single Thread, multiple Fiber environment, + # disable the multithread Mutex as it will not work. +# DEFAULT_OPTIONS[:multithread] = false - return @sock if @sock and not @sock.closed? + module EventedServer - @sock = nil + def fiber_key + @fiber_key ||= "memcached-#{@host}-#{@port}" + end + + def socket + sock = Thread.current[fiber_key] + return sock if sock and not sock.closed? - # If the host was dead, don't retry for a while. - return if @retry and @retry > Time.now + Thread.current[fiber_key] = nil + + # If the host was dead, don't retry for a while. + return if @retry and @retry > Time.now - fiber = Fiber.current - @sock = EM::SocketConnection.connect(@host, @port, @timeout) - yielding = true - @sock.callback do - @status = 'CONNECTED' + Thread.current[fiber_key] ||= begin + sock = EM::SocketConnection.connect(@host, @port, @timeout) + yielding = true + fiber = Fiber.current + sock.callback do + @status = 'CONNECTED' + @retry = nil + yielding = false + fiber.resume if Fiber.current != fiber + end + sock.errback do + sock = nil + yielding = false + fiber.resume if Fiber.current != fiber + end + Fiber.yield if yielding + sock + end + end + + def close + sock = Thread.current[fiber_key] + if sock + sock.close if !sock.closed? + Thread.current[fiber_key] = nil + end @retry = nil - yielding = false - fiber.resume if Fiber.current != fiber + @status = "NOT CONNECTED" end - @sock.errback do - yielding = false - fiber.resume if Fiber.current != fiber - end - Fiber.yield if yielding - @sock + end - end module EM module SocketConnection include EM::Deferrable @@ -125,10 +145,14 @@ @connected = true succeed end def unbind - @connected = false + if @connected + @connected = false + else + fail + end end private BUFFER_SIZE = 4096 \ No newline at end of file