Xavante / Compat-5.1: reloading a module?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Xavante / Compat-5.1: reloading a module?

William Trenker
What is the "proper" way to reload a module on the fly?  I am running
Xavante and have a custom handler that uses a module.  I want to be
able to change the module's source code and have the changes re-loaded
automatically without stopping Xavante.

I've been doing this:

--- myXavanteHandler.lua ---
module("myXavanteHandler")
local function myHandler(req, res, param)
    package.loaded.myModule = nil
    require"myModule"
    res.content = myModule.html(req.built_url)
    return res
end
function makeHandler (params)
    return function (req, res)
        return myHandler(req, res, params[1])
    end
end
--- end code ---

--- myModule.lua ---
module("myModule")
function html(txt)
    return "txt = "..txt.."<br />"
end
--- end code ---

The net effect is that when I change the code in myModule.lua, it will
be reloaded the next time the handler is called.

But is setting package.loaded.x to nil the design-intended way to
trigger a reload?  Will this cause problems with package.preload?

Thanks,
Bill


Reply | Threaded
Open this post in threaded view
|

Re: Xavante / Compat-5.1: reloading a module?

Tomas-14
	Hi Bill,

But is setting package.loaded.x to nil the design-intended way to
trigger a reload?
	Yes.

Will this cause problems with package.preload?
	I don't think so.  package.preload is intended to be used
by applications which are already linked against some libraries (which
is not the case of Xavante) and need to "register" the open functions
of these libraries to be used by require().

	Tomas

Reply | Threaded
Open this post in threaded view
|

Re: Xavante / Compat-5.1: reloading a module?

Javier Guerra Giraldez
In reply to this post by William Trenker
On Tuesday 02 August 2005 2:26 pm, William Trenker wrote:
> What is the "proper" way to reload a module on the fly?  I am running
> Xavante and have a custom handler that uses a module.  I want to be
> able to change the module's source code and have the changes re-loaded
> automatically without stopping Xavante.

i think in your case it's easier to use loadfile() instead of require()

something like:

local lastT = 0
local lastFunc

function getScript (n)
    local attr = lfs.attributes (n)
    local t = attr.modification
    if t > lastT then
        lastFunc = loadfile (n)
        lastT = attr.modification
    end
    return lastFunc
end

then you just call getScript(), and it'll reload your module only if it has 
been modified.

-- 
Javier

Attachment: pgp3c7UJyHv6p.pgp
Description: PGP signature

Reply | Threaded
Open this post in threaded view
|

Re: Xavante / Compat-5.1: reloading a module?

William Trenker
On 8/2/05, Javier Guerra <[hidden email]> wrote:
> On Tuesday 02 August 2005 2:26 pm, William Trenker wrote:
> > What is the "proper" way to reload a module on the fly?
> 
> i think in your case it's easier to use loadfile() instead of require()
> 

Hi Javier,

I really like your idea of checking to see if the script has changed. 
The reason I was focussing on require() is that I get the benefits of
the built-in LUA_PATH searching and the dotted notation for module
names.

Taking an idea from Python, I wonder if it would be beneficial for the
new module system to extend the package.loaded concept to include
keeping some information about each loaded module -- such as the
module's full path?  Then one could expand on your reloading script
and interface it with the module system -- perhaps along the lines of
this pseudocode:

function reloadModuleIfChanged(moduleName)
    if not package.loaded[moduleName] then
        -- first time loaded: initialize module information
        require(moduleName)
        -- assume require has saved the module's path
        -- in package.info[moduleName].modulePath
        local info = package.info[moduleName]
        local t = lsf.attributes(info.modulePath).modification
        package.info[moduleName].lastT = t
    else
        -- module already loaded: check if module's
        -- source code has changed
        local info = package.info[moduleName]
        local attr = lfs.attributes (info.modulePath)
        local t = attr.modification
        if t > info.lastT then
            -- module's code has changed: reload it
            package.loaded[moduleName] = nil
            require(moduleName)
            info.lastT = attr.modification
        else
            -- module hasn't changed: do nothing
        end
    end
end

The above code sketch is probably not the most efficient way to do
this and is likely incomplete but I hope it paints the picture.

Thanks for the input,
Bill