I'm trying to hot reload a Lua module but the standard way to do it doesn't seem to be working in my case.
I have created 2 simple example modules, 'app.lua' and 'test.lua', where the former one serves as an entry point to the application:
# app.lua
test2 = require("test")
while 1 > 0 do
test2.p()
end
and loads a function from the latter one:
# test.lua
local test = {}
function test.p()
print("!!!")
end
return test
This application is running in a docker container build from an official Tarantool image. Let's suppose I have made changes in the code of the 'test' module, say, changed the line with print to 'print("???")'. The standard way to reload a module is to enter the tarantool console on a container and assign nil
to the package.loaded['<name_module>']
. However, when I type it in, the console says it's already null:
tarantool> package.loaded['test']
---
- null
...
What am I doing wrong here?
You may see package.loaded['test'] == nil
because you don't connect to Tarantool instance.
Usually when you connect to Tarantool you look something like
connected to localhost:3301
localhost:3301>
Seems you simply enter to docker container and then run "tarantool". This way you just run new Tarantool instance that knows nothing about your application.
You can connect to tarantool instance with console
command (right in container) or tarantoolctl connect login:password@host:port
(for default configuration tarantoolctl connect 3301
works, for details see here) or attach and then check package.loaded['test']
value.
Here's a simplified approach for reloading code of your modules:
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
}
More complex, but proper way is to use the package-reload module.
Here's an explanation why your code didn't work:
-- 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
Then you do package.loaded['test'] = nil
and
drop a key from package.loaded
table.
Note, you don't drop value because you have
a reference (test2 in your case) in your "app.lua" file.