在 Tarantool 上热重载 Lua 应用程序时出现问题

Problem with hot reloading Lua app on Tarantool

我正在尝试热重载 Lua 模块,但标准方法似乎对我来说不起作用。

我创建了 2 个简单的示例模块,'app.lua' 和 'test.lua',其中前一个用作应用程序的入口点:

# app.lua
test2 = require("test")

while 1 > 0 do
    test2.p()
end

并从后者加载一个函数:

# test.lua
local test = {}
function test.p()
    print("!!!")
end

return test

此应用程序 运行 在 docker 容器构建中,来自官方 Tarantool 映像。假设我对 'test' 模块的代码进行了更改,例如,将带有 print 的行更改为 'print("???")'。重新加载模块的标准方法是在容器上进入 tarantool 控制台并将 nil 分配给 package.loaded['<name_module>']。但是,当我输入它时,控制台显示它已经为空:

tarantool> package.loaded['test']
---
- null
...

我做错了什么?

您可能会看到 package.loaded['test'] == nil,因为您没有连接到 Tarantool 实例。

通常当您连接到 Tarantool 时,您看起来像

connected to localhost:3301
localhost:3301> 

似乎你只是进入 docker 容器然后 运行“塔兰图尔”。这样您就可以 运行 对您的应用程序一无所知的新 Tarantool 实例。

您可以使用 console 命令(就在容器中)或 tarantoolctl connect login:password@host:port(对于默认配置 tarantoolctl connect 3301 有效,有关详细信息,请参阅 here) or attach 然后检查 package.loaded['test'] 值。

这是重新加载模块代码的简化方法:

test2 = require("test")

local function reload()
    package.loaded['test'] = nil -- clean module cache
    test2 = require('test') -- update a reference to test2 with new code
end

while 1 > 0 do
    test2.p()
end

return {
   reload = reload,  -- require('app').reload() in your console for reload
}

更复杂,但正确的方法是使用 package-reload 模块。

以下是您的代码无法正常工作的原因:

-- Here you require "test" module
-- Lua check package.loaded['test'] value
-- and if it's nil then physically load file
-- from disk (see dofile function).
--
-- Well, you got a reference to table with
-- your "p" function.
test2 = require("test")

-- Here you've already has a reference
-- to "test" module.
-- It's static, you don't touch it here.
while 1 > 0 do
    test2.p()
end

然后你 package.loaded['test'] = nil 然后 从 package.loaded table 中删除一个密钥。 请注意,您不会降低价值,因为您有 您的“app.lua”文件中的参考(在您的情况下为 test2)。