1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
begin
require "remcached"
rescue LoadError => error
raise "Missing EM-Synchrony dependency: gem install remcached"
end
module Memcached
class << self
def connect(servers)
Memcached.servers = servers
f = Fiber.current
@w = EM::Timer.new(10.0) { f.resume :error }
@t = EM::PeriodicTimer.new(0.01) do
if Memcached.usable?
@w.cancel
@t.cancel
f.resume(self)
end
end
r = Fiber.yield
(r == :error) ? (raise Exception.new('Cannot connect to memcached server')) : r
end
%w[add get set delete].each do |type|
class_eval %[
def a#{type}(contents, &callback)
df = EventMachine::DefaultDeferrable.new
df.callback &callback
cb = Proc.new { |res| df.succeed(res) }
operation Request::#{type.capitalize}, contents, &cb
df
end
def #{type}(contents, &callback)
fiber = Fiber.current
paused = false
cb = Proc.new do |res|
if paused
fiber.resume(res)
else
return res
end
end
df = a#{type}(contents, &cb)
df.callback &callback
paused = true
Fiber.yield
end
]
end
%w[add get set delete].each do |type|
class_eval %[
def amulti_#{type}(contents, &callback)
df = EventMachine::DefaultDeferrable.new
df.callback &callback
cb = Proc.new { |res| df.succeed(res) }
multi_operation Request::#{type.capitalize}, contents, &cb
df
end
def multi_#{type}(contents, &callback)
fiber = Fiber.current
paused = false
cb = Proc.new do |res|
if paused
fiber.resume(res)
else
return res
end
end
df = amulti_#{type}(contents, &cb)
df.callback &callback
paused = true
Fiber.yield
end
]
end
end
end
|