123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- local skynet = require "skynet"
- require "skynet.manager"
- local logger = require "logger"
- local common_fun = require "model.common_fun"
- local stringify = require "stringify"
- local pipeline = require "pipeline"
- local redisdriver = require "skynet.db.redis"
- local KEY_STR = "itemavg"
- local util = require "util"
- local redis
- local cjson = require "cjson"
- cjson.encode_sparse_array(true, 1)
- local cjson_decode = cjson.decode -- 解码
- local cjson_encode = cjson.encode -- 编码
- local change = false
- local CMD = {}
- local function toFixed(a, b)
- local num = 10 ^ b
- local ret = math.floor(a * num + 0.5)/num
- return ret
- end
- local clear_time = 0
- local avglist = {
- --[[
- [id] = {
- list = {
- [lv] = {
- num = 人数,
- avg = 平均,
- }
- }
- all = {num, avg}
- }
- ]]
- }
- local function init()
- local conf = assert(option.redis)
- redis = redisdriver.connect(conf)
- redis:select(12)
- local retnuma = redis:hgetall(KEY_STR)
- local time = redis:get(KEY_STR..":clear_time")
- if time then
- clear_time = tonumber(time) or 0
- end
- for k = 1, #retnuma, 2 do
- local key = tostring(retnuma[k])
- if key then
- avglist[key] = cjson_decode(retnuma[k+1])
- end
- end
- end
- local function save()
- if change then
- local batch = pipeline(124)
- for id, data in pairs(avglist) do
- batch.add("hset", KEY_STR, id, cjson_encode(data))
- end
- batch.execute(redis)
- change = false
- end
- end
- function CMD.updata(data)
- if not data then
- return
- end
- local lv = tostring(data.level)
- for _, v in ipairs(data.list or {})do
- local key = tostring(v.id)
- local num = v.num
- avglist[key] = avglist[key] or {
- list = {},
- all = {num = 0, avg = 0}
- }
- avglist[key].list[lv] = avglist[key].list[lv] or {
- num = 0,
- avg = 0,
- }
- local all = avglist[key].all
- local cur = avglist[key].list[lv]
- all.num = all.num + 1
- all.avg = all.avg + toFixed((num - all.avg)/all.num, 2)
- cur.num = cur.num + 1
- cur.avg = cur.avg + toFixed((num - cur.avg)/cur.num, 2)
- end
- change = true
- end
- function CMD.show(id)
- if not id then
- return stringify(avglist)
- end
- return stringify(avglist[id] or {})
- end
- local function check_clear(time)
- if time > clear_time then
- clear_time = util.today()+DAY_SEC
- redis:set(KEY_STR..":clear_time", clear_time)
- avglist = {}
- redis:del(KEY_STR)
- change = false
- end
- end
- local function watchtime()
- skynet.fork(function()
- local interval = 1-- 更新间隔为2分钟
- local up_time = os.time()
- while(true) do
- local now = os.time()
- if now > up_time then
- up_time = up_time + interval
- check_clear(now)
- save()
- end
- skynet.sleep(100)
- end
- end)
- end
- function CMD.start()
- init()
- watchtime()
- end
- skynet.init(function()
- skynet.register(".itemavg")
- end)
-
- skynet.start(function()
- skynet.dispatch("lua", function(session, _, cmd, ...)
- local f = assert(CMD[cmd])
- if 0==session then
- f(...)
- else
- skynet.retpack(f(...))
- end
- end)
- end)
-
|