mod_inotify_reload/mod_inotify_reload.lua
author Kim Alvefur <zash@zash.se>
Sun, 03 Mar 2024 11:23:40 +0100
changeset 5857 97c9b76867ca
parent 5399 82207f936f1f
permissions -rw-r--r--
mod_log_ringbuffer: Detach event handlers on logging reload (thanks Menel) Otherwise the global event handlers accumulate, one added each time logging is reoladed, and each invocation of the signal or event triggers one dump of each created ringbuffer.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
652
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
-- mod_inotify_reload
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
-- Reloads modules when their files change
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
-- Depends on linotify: https://github.com/hoelzro/linotify
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
module:set_global();
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
local inotify = require "inotify";
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
local modulemanager = require "core.modulemanager";
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
local inh = inotify.init();
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
local watches = {};
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
local watch_ids = {};
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
5399
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    15
require"net.server".watchfd(inh:fileno(), function()
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    16
	local events = inh:read();
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    17
	for _, event in ipairs(events) do
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    18
		local mod = watches[watch_ids[event.wd]];
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    19
		if mod then
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    20
			local host, name = mod.host, mod.name;
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    21
			module:log("debug", "Reloading changed module mod_%s on %s", name, host);
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    22
			modulemanager.reload(host, name);
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    23
		else
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    24
			module:log("warn", "no watch for %d", event.wd);
652
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
		end
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
	end
5399
82207f936f1f mod_inotify_reload: Update to use FD watching method
Kim Alvefur <zash@zash.se>
parents: 744
diff changeset
    27
end);
652
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
function watch_module(name, host, path)
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
	local id, err = inh:addwatch(path, inotify.IN_CLOSE_WRITE);
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
	if not id then return nil, err; end
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
	local k = host.."\0"..name;
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
	watches[k] = { id = id, path = path, name = name, host = host };
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
	watch_ids[id] = k;
744
ab988e98a9f9 mod_inotify_reload: Add debug logging
Matthew Wild <mwild1@gmail.com>
parents: 652
diff changeset
    35
	module:log("debug", "Watching %s:%s with id %d", name, host, id);
652
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	return true;
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
end
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
function unwatch_module(name, host)
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
	local k = host.."\0"..name;
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
	if not watches[k] then
744
ab988e98a9f9 mod_inotify_reload: Add debug logging
Matthew Wild <mwild1@gmail.com>
parents: 652
diff changeset
    42
		module:log("warn", "Not watching %s:%s", name, host);
652
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
		return nil, "not-watching";
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
	end
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
	local id = watches[k].id;
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
	local ok, err = inh:rmwatch(id);
744
ab988e98a9f9 mod_inotify_reload: Add debug logging
Matthew Wild <mwild1@gmail.com>
parents: 652
diff changeset
    47
	module:log("info", "Removed watch %d", id);
652
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
	watches[k] = nil;
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
	watch_ids[id] = nil;
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
	return ok, err;
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
end
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
function module_loaded(event)
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
	local host, name = event.host, event.module;
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
	local path = modulemanager.get_module(host, name).module.path;
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
	if not path then
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
		module:log("warn", "Couldn't watch mod_%s, no path", name);
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
		return;
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
	end
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
	if watch_module(name, host, path) then
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
		module:log("debug", "Watching mod_%s", name);
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
	end
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
end
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
function module_unloaded(event)
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
	unwatch_module(event.module, event.host);
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
end
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
function module.add_host(module)
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
	module:hook("module-loaded", module_loaded);
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
	module:hook("module-unloaded", module_unloaded);
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
end
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
module:hook("module-loaded", module_loaded);
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
module:hook("module-unloaded", module_unloaded);
3e6f43ab7e22 mod_inotify_reload: Reload modules when their code changes
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76