【问题标题】:tarantool how to handle lua errors outside the fibertarantool 如何处理光纤外的 lua 错误
【发布时间】:2020-10-07 16:26:38
【问题描述】:

我想知道,如何设置光纤错误抛出的回调。

示例:

local fiber = require("fiber")
local status = 0 --in my case stored in db

local function time_consuming()
    lua_error
    status = 0
end

function external_api_function()
    if status == 1 then return "already running" end

    status = 1
    fiber.create(time_consuming)
    return "started"
end

所以如果time_consuming 函数失败,我想将状态设置为 0。有什么方法可以抓到吗?

我考虑在下次访问 api 时检查 fiber:status。如果我希望状态有效,或者为光纤创建一个看门狗。这对我有用,但似乎不是最好的解决方案。

【问题讨论】:

    标签: tarantool fibers


    【解决方案1】:

    有多种方法可以实现您的目标。

    在您的示例中,两个纤程(maintime_consuming 任务)共享相同的范围 - status 变量。如果您更改子纤程中status 变量的值,父纤程将看到更新。您可以使用简单的 sn-p 进行检查:

    status = 1
    fiber.create(function() status = 0 end)
    print(status) -- 0
    

    现在,要捕获异常,请使用pcall 函数。它接受一个函数作为第一个参数,调用它并在一个或多个函数结果之后将状态作为第一个值返回。如果要分析捕获的错误,还有xpcall 函数。它将错误处理程序作为第二个参数。

    使用pcall,您可以像这样更改time_consuming 函数:

    local function time_consuming()
        local ok = pcall(function() lua_error end)
        if not ok then
            status = 0
        end
    end
    

    如果lua_error 失败,status 将成功更新。

    但通常我认为这是一种不好的做法。如果更多的纤程共享相同的状态,由于纤程执行顺序的不确定性,可能会变得难以维护。因此,对于更可靠的解决方案,您可能需要使用光纤间通信原语,即 channels。您将能够使用channel:put()channel:get() 函数明确要求子纤程告诉您其执行状态是否成功。有关示例,请参阅文档。

    【讨论】:

    • 另外,请注意,如果你想创建一个看门狗光纤,你需要实现一个循环,它会不断重复一些动作。否则,您的语句将被评估,并且 Fiber 将在内部函数返回后立即失效。通常它是一个简单的while true do ... end 循环,但可能会有变化。查看fiber documentation 了解更多信息。
    猜你喜欢
    • 2016-10-21
    • 2013-07-30
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多