基于skynet 的lua协程挂超时唤醒

场景描述:
A程序有A1,A2两个操作需要执行
B程序有B1,B2两个操作需要执行

表面逻辑:A程序需要获取B程序的数据(B不能直接回复A消息,需要通过另一个通道通知)
细节逻辑:A程序需要执行A1后,发送消息给B1,B1执行消息后使用B2消息回复A程序,发送给A2,A2去唤醒A1,A程序A1就得到了数据。A2的作用是接收数据,处理数据。

带有日志的代码如下,成功执行step1,2,3,4,5表示程序正常

local skynet = require "skynet"
local skynetmgr = require "skynet.manager"
local json = require 'json'
local httpc = require "http.httpc"
local CONFIG = require "config"
local queue = require "skynet.queue"
local coroutine = require "skynet.coroutine"

CMD = {}
ussoperation = {}

local function wake_up_regularly(dataid)
    -- 等待30秒
    skynet.sleep(3000)
    
    if ussoperation[tostring(dataid)].func ~= "" then
        print("===================4======================",os.date('%Y-%m-%d %H:%M:%S', os.time()),dataid,"Timeout awaken")
        local func = ussoperation[tostring(dataid)].func 
        ussoperation[tostring(dataid)].func = ''
        skynet.wakeup(func)
    else
        print("===================任务已结束======================",os.date('%Y-%m-%d %H:%M:%S', os.time()),dataid)
    end
    
    return
end

-- 获取函数A1函数
local function get_data(dataid)
    print("===================1======================",os.date('%Y-%m-%d %H:%M:%S', os.time()),dataid)
    ussoperation[tostring(dataid)] = {}
    ussoperation[tostring(dataid)].func = coroutine.running()
    -- 超时唤醒
    print("===================2======================",os.date('%Y-%m-%d %H:%M:%S', os.time()),dataid)
    skynet.fork(wake_up_regularly,dataid)
    -- 挂起,等待采集到数据后唤醒
    print("===================3======================",os.date('%Y-%m-%d %H:%M:%S', os.time()),dataid)
    skynet.wait()
    print("===================5======================",os.date('%Y-%m-%d %H:%M:%S', os.time()),dataid)
    ussoperation[tostring(dataid)].func = ''
    return {code=0,msg="success"}
end

-- 新建获取数据的任务
function CMD.TEMPPIC(para)
    if ussoperation[tostring(para.id)].func ~= "" then
        local func = ussoperation[tostring(para.id)].func 
        ussoperation[tostring(para.id)].func = ''
        skynet.wakeup(func)
        print("===================4======================",os.date('%Y-%m-%d %H:%M:%S', os.time()),para.id,"Normal wake up")
    else
        return {code=-1,msg="fail"}
    end
    print("===============TEMPPIC END========================")
    return {code=0,msg="success"}
end

-- 接收数据A2函数
function CMD.TEMPPICCMD(para)
    print(json.encode(para))
    skynet.fork(get_data,para.id)
    return {code=0,msg="success"}
end

function initialise()
    skynet.fork(get_data,456789)
end

skynet.start(function()
    skynet.dispatch("lua", function(session, address, cmd, ...)
        cmd = cmd:upper()
        local f = CMD[cmd]
        if f then
            skynet.ret(skynet.pack(f(...)))
        else
            local msg = string.format("Unknown command %s", tostring(cmd))
            skynet.retpack({{errno=-1, badresult=true, err=msg, sqlstate=0}})
        end
    end)

    initialise()

    skynet.register(".mywake")
end)

有两个任务一个是789任务,另一个是456789任务
image

posted @ 2021-12-18 19:19  Smah  阅读(276)  评论(0编辑  收藏  举报