lib/remcached.rb in astro-remcached-0.2.2 vs lib/remcached.rb in astro-remcached-0.3.0

- old
+ new

@@ -54,33 +54,100 @@ i += 1 end hashed end - def operation(op, contents, &callback) + + ## + # Memcached operations + ## + + def operation(request_klass, contents, &callback) client = client_for_key(contents[:key]) if client - client.send(op, contents, &callback) + client.send_request request_klass.new(contents), &callback elsif callback callback.call :status => Errors::DISCONNECTED end end - - ## - # Memcached operations - ## - def add(contents, &callback) - operation :add, contents, &callback + operation Request::Add, contents, &callback end def get(contents, &callback) - operation :get, contents, &callback + operation Request::Get, contents, &callback end def set(contents, &callback) - operation :set, contents, &callback + operation Request::Set, contents, &callback end def delete(contents, &callback) - operation :delete, contents, &callback + operation Request::Delete, contents, &callback end + + + ## + # Multi operations + # + ## + + def multi_operation(request_klass, contents_list, &callback) + results = {} + + # Assemble client connections per keys + client_contents = {} + contents_list.each do |contents| + client = client_for_key(contents[:key]) + if client + client_contents[client] ||= [] + client_contents[client] << contents + else + puts "no client for #{contents[:key].inspect}" + results[contents[:key]] = {:status => Memcached::Errors::DISCONNECTED} + end + end + + # send requests and wait for responses per client + clients_pending = client_contents.length + client_contents.each do |client,contents_list| + last_i = contents_list.length - 1 + client_results = {} + + contents_list.each_with_index do |contents,i| + if i < last_i + request = request_klass::Quiet.new(contents) + client.send_request(request) { |response| + results[contents[:key]] = response + } + else # last request for this client + request = request_klass.new(contents) + client.send_request(request) { |response| + results[contents[:key]] = response + clients_pending -= 1 + if clients_pending < 1 + callback.call results + end + } + end + end + end + + self + end + + def multi_add(contents_list, &callback) + multi_operation Request::Add, contents_list, &callback + end + + def multi_get(contents_list, &callback) + multi_operation Request::Get, contents_list, &callback + end + + def multi_set(contents_list, &callback) + multi_operation Request::Set, contents_list, &callback + end + + def multi_delete(contents_list, &callback) + multi_operation Request::Delete, contents_list, &callback + end + end end