local skynet = require "skynet" require "utils.init" local redisd_count = tonumber(skynet.getenv("thread")) local redisd skynet.init(function() local idx = math.randomInt(1, redisd_count) redisd = skynet.localname(".redis" .. idx) end) local table_insert = table.insert local redisproxy = {} local isUsePika = false setmetatable(redisproxy, { __index = function(t, k) local cmd = string.upper(k) local f = function (self, ...) local ok, result = pcall(skynet.call, redisd, "lua", cmd, ...) if not ok then skynet.error(cmd, ..., "\n", debug.traceback(coroutine.running(), nil)) return end return result end t[k] = f return f end}) function redisproxy:runScripts(name, ...) local RedisScripts = require("rdsscripts/RedisScripts") if not RedisScripts[name].sha1 then local content = io.readfile(RedisScripts[name].file) RedisScripts[name].sha1 = self:script("LOAD", content) end -- 不存在脚本(系统问题或者需要刷新脚本) local existScript = self:script("EXISTS", RedisScripts[name].sha1) if existScript[1] == 0 then local content = io.readfile(RedisScripts[name].file) RedisScripts[name].sha1 = self:script("LOAD", content) end return self:evalsha(RedisScripts[name].sha1, ...) end local meta = {__index = function (tab, name) return function (_, ...) tab[#tab+1]={name, ...} end end} function redisproxy:pipelining(block, transaction) if transaction == nil then transaction = true end -- 默认具有事务性 if isUsePika then transaction = false end local ops = setmetatable({}, meta) if transaction then ops[#ops+1]={"multi"} end block(ops) if transaction then if #ops == 1 then return end ops[#ops+1]={"exec"} else if #ops == 0 then return end end return self:pipeline(ops, transaction) end if isUsePika then function redisproxy:insertEmail(params) local roleId = params.roleId local emailId = params.emailId local createtime = params.createtime or skynet.timex() local contentPms = params.contentPms or {} local rewardPms = params.rewardPms or {} local title = params.title or "" local stitle = params.stitle or "" local content = params.content or "" local attachments = params.attachments or "" local id = self:HINCRBY(string.format("role:%d:autoincr", roleId), "email", 1) self:LPUSH(string.format("role:%d:emailIds", roleId), id) local deleteIds = self:LRANGE(string.format("role:%d:emailIds", roleId), EMAIL_LIMIT, -1) self:pipelining(function(red) for _, deleteId in ipairs(deleteIds) do red:DEL(string.format("email:%d:%d", roleId, deleteId)) end red:LTRIM(string.format("role:%d:emailIds", roleId), 0, EMAIL_LIMIT - 1) red:HMSET(string.format("email:%d:%d", roleId, id), "id", tostring(id), "emailId", emailId, "status", "0", "createtime", createtime, "contentPms", MsgPack.pack(contentPms), "rewardPms", MsgPack.pack(rewardPms), "title", title, "stitle", stitle, "content", content, "attachments", attachments) end) end else function redisproxy:insertEmail(params) local pms = { roleId = params.roleId, emailId = params.emailId, createtime = params.createtime or skynet.timex(), contentPms = params.contentPms or {}, rewardPms = params.rewardPms or {}, title = params.title or "", stitle = params.stitle or "", content = params.content or "", attachments = params.attachments or "", } self:runScripts("insertEmail", 10, EMAIL_LIMIT, pms.roleId, pms.emailId, pms.createtime, MsgPack.pack(pms.contentPms), MsgPack.pack(pms.rewardPms), pms.title, pms.stitle, pms.content, pms.attachments) return true end end return redisproxy