redisproxy.lua 3.53 KB
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