mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 12:20:41 +00:00
batch mode in redis
This commit is contained in:
@@ -2,8 +2,10 @@ local skynet = require "skynet"
|
|||||||
local string = string
|
local string = string
|
||||||
local table = table
|
local table = table
|
||||||
local unpack = unpack
|
local unpack = unpack
|
||||||
|
local assert = assert
|
||||||
|
|
||||||
local redis_manager
|
local redis_manager
|
||||||
|
local batch = false
|
||||||
|
|
||||||
local redis = {}
|
local redis = {}
|
||||||
|
|
||||||
@@ -12,21 +14,40 @@ local command = {}
|
|||||||
setmetatable(command, { __index = function(t,k)
|
setmetatable(command, { __index = function(t,k)
|
||||||
local cmd = string.upper(k)
|
local cmd = string.upper(k)
|
||||||
local f = function(self, ...)
|
local f = function(self, ...)
|
||||||
local err, result = skynet.call( self.__handle, "lua", cmd, ...)
|
if batch then
|
||||||
assert(err, result)
|
skynet.send( self.__handle, "lua", cmd , ...)
|
||||||
return result
|
else
|
||||||
|
local err, result = skynet.call( self.__handle, "lua", cmd, ...)
|
||||||
|
assert(err, result)
|
||||||
|
return result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
t[k] = f
|
t[k] = f
|
||||||
return f
|
return f
|
||||||
end})
|
end})
|
||||||
|
|
||||||
function command:exists(key)
|
function command:exists(key)
|
||||||
|
assert(not batch, "exists can't used in batch mode")
|
||||||
local result , exists = skynet.call( self.__handle, "lua" , "EXISTS", key)
|
local result , exists = skynet.call( self.__handle, "lua" , "EXISTS", key)
|
||||||
assert(result, exists)
|
assert(result, exists)
|
||||||
exists = exists ~= 0
|
exists = exists ~= 0
|
||||||
return exists
|
return exists
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function command:batch(mode)
|
||||||
|
if mode == "end" then
|
||||||
|
assert(batch, "Open batch mode first")
|
||||||
|
batch = false
|
||||||
|
local err, result = skynet.unpack(skynet.rawcall( self.__handle, "text", mode))
|
||||||
|
assert(err, result)
|
||||||
|
return result
|
||||||
|
else
|
||||||
|
assert(mode == "read" or mode == "write")
|
||||||
|
batch = mode
|
||||||
|
skynet.send( self.__handle, "text", mode)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local meta = {
|
local meta = {
|
||||||
__index = command
|
__index = command
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ local table = table
|
|||||||
local tonumber = tonumber
|
local tonumber = tonumber
|
||||||
local ipairs = ipairs
|
local ipairs = ipairs
|
||||||
local unpack = unpack
|
local unpack = unpack
|
||||||
|
local batch_mode = {}
|
||||||
|
local batch_count = {}
|
||||||
|
local batch_reply = {}
|
||||||
local redis_server, redis_db = ...
|
local redis_server, redis_db = ...
|
||||||
|
|
||||||
local function compose_message(msg)
|
local function compose_message(msg)
|
||||||
@@ -46,9 +49,48 @@ local function pop_request_queue()
|
|||||||
return reply
|
return reply
|
||||||
end
|
end
|
||||||
|
|
||||||
local function response(...)
|
local function batch_close(address,session)
|
||||||
|
local reply = batch_reply[address]
|
||||||
|
skynet.redirect(address,0, "response", session, skynet.pack(not (type(reply) == "string"), reply))
|
||||||
|
batch_mode[address] = nil
|
||||||
|
batch_count[address] = nil
|
||||||
|
batch_reply[address] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function batch_dec(address)
|
||||||
|
local bc = batch_count[address]
|
||||||
|
batch_count[address] = bc - 1
|
||||||
|
if bc == 1 then
|
||||||
|
local session = batch_mode[address]
|
||||||
|
if type(session) == "number" then
|
||||||
|
batch_close(address, session)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function response(suc, value)
|
||||||
local reply = pop_request_queue()
|
local reply = pop_request_queue()
|
||||||
skynet.redirect(reply.address,0, "response", reply.session, skynet.pack(...))
|
local mode = reply.batch
|
||||||
|
local address = reply.address
|
||||||
|
if mode == "read" then
|
||||||
|
if suc then
|
||||||
|
local br = batch_reply[address]
|
||||||
|
if type(br) == "table" then
|
||||||
|
br.n = br.n + 1
|
||||||
|
br[br.n] = value
|
||||||
|
end
|
||||||
|
else
|
||||||
|
batch_reply[address] = value
|
||||||
|
end
|
||||||
|
batch_dec(address)
|
||||||
|
elseif mode == "write" then
|
||||||
|
if not suc then
|
||||||
|
batch_reply[address] = value
|
||||||
|
end
|
||||||
|
batch_dec(address)
|
||||||
|
else
|
||||||
|
skynet.redirect(address,0, "response", reply.session, skynet.pack(suc, value))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function readline(sep)
|
local function readline(sep)
|
||||||
@@ -159,11 +201,37 @@ skynet.register_protocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
|
skynet.dispatch("text", function(session, address, mode)
|
||||||
|
local last = batch_mode[address]
|
||||||
|
if mode == "end" then
|
||||||
|
assert(last == "read" or last == "write" , "Invalid end")
|
||||||
|
if batch_count[address] == 0 then
|
||||||
|
batch_close(address, session)
|
||||||
|
else
|
||||||
|
batch_mode[address] = session
|
||||||
|
end
|
||||||
|
else
|
||||||
|
assert(last == nil, "Already in batch mode")
|
||||||
|
if mode == "read" then
|
||||||
|
batch_reply[address] = { n = 0 }
|
||||||
|
batch_count[address] = 0
|
||||||
|
elseif mode == "write" then
|
||||||
|
batch_count[address] = 0
|
||||||
|
else
|
||||||
|
error ("Invalid last batch operation : " .. last)
|
||||||
|
end
|
||||||
|
batch_mode[address] = mode
|
||||||
|
end
|
||||||
|
end)
|
||||||
skynet.dispatch("lua", function(session, address, ...)
|
skynet.dispatch("lua", function(session, address, ...)
|
||||||
local message = { ... }
|
local message = { ... }
|
||||||
local cmd = compose_message(message)
|
local cmd = compose_message(message)
|
||||||
socket.write(cmd)
|
socket.write(cmd)
|
||||||
push_request_queue { session = session , address = address, cmd = cmd }
|
local mode = batch_mode[address]
|
||||||
|
if mode == "read" or mode == "write" then
|
||||||
|
batch_count[address] = batch_count[address] + 1
|
||||||
|
end
|
||||||
|
push_request_queue { session = session , address = address, cmd = cmd , batch = mode }
|
||||||
end)
|
end)
|
||||||
init()
|
init()
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -3,9 +3,22 @@ local redis = require "redis"
|
|||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
local db = redis.connect "main"
|
local db = redis.connect "main"
|
||||||
|
db:batch "write" -- ignore results
|
||||||
|
db:set("A", "hello")
|
||||||
|
db:set("B", "world")
|
||||||
|
db:batch "end"
|
||||||
|
|
||||||
|
db:batch "read"
|
||||||
|
db:get("A")
|
||||||
|
db:get("B")
|
||||||
|
local r = db:batch "end" -- return all results in a table
|
||||||
|
for k,v in pairs(r) do
|
||||||
|
print(k,v)
|
||||||
|
end
|
||||||
print(db:exists "A")
|
print(db:exists "A")
|
||||||
print(db:get "A")
|
print(db:get "A")
|
||||||
print(db:set("A","hello world"))
|
print(db:set("A","hello world"))
|
||||||
|
print(db:get("A"))
|
||||||
skynet.exit()
|
skynet.exit()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user