Changeset

569:5216efe6088b

Add hostmanager, and eventmanager
author Matthew Wild <mwild1@gmail.com>
date Sat, 06 Dec 2008 03:41:49 +0000
parents 568:b2464849c1b0
children 572:b2d665689df7
files core/eventmanager.lua core/hostmanager.lua core/modulemanager.lua core/sessionmanager.lua prosody tests/test.lua
diffstat 6 files changed, 157 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/eventmanager.lua	Sat Dec 06 03:41:49 2008 +0000
@@ -0,0 +1,25 @@
+
+local t_insert = table.insert;
+local ipairs = ipairs;
+
+module "eventmanager"
+
+local event_handlers = {};
+
+function add_event_hook(name, handler)
+	if not event_handlers[name] then
+		event_handlers[name] = {};
+	end
+	t_insert(event_handlers[name] , handler);
+end
+
+function fire_event(name, ...)
+	local event_handlers = event_handlers[name];
+	if event_handlers then
+		for name, handler in ipairs(event_handlers) do
+			handler(...);
+		end
+	end
+end
+
+return _M;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/hostmanager.lua	Sat Dec 06 03:41:49 2008 +0000
@@ -0,0 +1,49 @@
+
+hosts = {};
+
+local hosts = hosts;
+local configmanager = require "core.configmanager";
+local eventmanager = require "core.eventmanager";
+
+local pairs = pairs;
+
+module "hostmanager"
+
+local function load_enabled_hosts(config)
+	local defined_hosts = config or configmanager.getconfig();
+	
+	for host, host_config in pairs(defined_hosts) do
+		if host ~= "*" and (host_config.core.enabled == nil or host_config.core.enabled) then
+			activate(host, host_config);
+		end
+	end
+end
+
+eventmanager.add_event_hook("server-starting", load_enabled_hosts);
+
+function activate(host, host_config)
+	hosts[host] = {type = "local", connected = true, sessions = {}, host = host, s2sout = {} };
+	
+	eventmanager.fire_event("host-activated", host, host_config);
+end
+
+function deactivate(host)
+	local host_session = hosts[host];
+	
+	eventmanager.fire_event("host-deactivating", host, host_session);
+	
+	-- Disconnect local users, s2s connections
+	for user, session_list in pairs(host_session.sessions) do
+		for resource, session in pairs(session_list) do
+			session:close("host-gone");
+		end
+	end
+	-- Components?
+	
+	hosts[host] = nil;
+	eventmanager.fire_event("host-deactivated", host);
+end
+
+function getconfig(name)
+end
+
--- a/core/modulemanager.lua	Sat Dec 06 03:40:51 2008 +0000
+++ b/core/modulemanager.lua	Sat Dec 06 03:41:49 2008 +0000
@@ -24,6 +24,8 @@
 local logger = require "util.logger";
 local log = logger.init("modulemanager");
 local addDiscoInfoHandler = require "core.discomanager".addDiscoInfoHandler;
+local eventmanager = require "core.eventmanager";
+
 
 local loadfile, pcall = loadfile, pcall;
 local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv;
@@ -182,28 +184,7 @@
 	end);
 end
 
-
-do
-	local event_handlers = {};
-	
-	function api:add_event_hook(name, handler)
-		if not event_handlers[name] then
-			event_handlers[name] = {};
-		end
-		t_insert(event_handlers[name] , handler);
-		self:log("debug", "Subscribed to %s", name);
-	end
-	
-	function fire_event(name, ...)
-		local event_handlers = event_handlers[name];
-		if event_handlers then
-			for name, handler in ipairs(event_handlers) do
-				handler(...);
-			end
-		end
-	end
-end
-
+api.add_event_hook = eventmanager.add_event_hook;
 
 local function _add_handler(module, origin_type, tag, xmlns, handler)
 	local handlers = stanza_handlers[module.host];
--- a/core/sessionmanager.lua	Sat Dec 06 03:40:51 2008 +0000
+++ b/core/sessionmanager.lua	Sat Dec 06 03:41:49 2008 +0000
@@ -35,6 +35,10 @@
 local rm_load_roster = require "core.rostermanager".load_roster;
 local config_get = require "core.configmanager".get;
 
+local fire_event = require "core.eventmanager".fire_event;
+
+local gettime = require "socket".gettime;
+
 local st = require "util.stanza";
 
 local newproxy = newproxy;
@@ -45,7 +49,7 @@
 local open_sessions = 0;
 
 function new_session(conn)
-	local session = { conn = conn,  priority = 0, type = "c2s_unauthed" };
+	local session = { conn = conn,  priority = 0, type = "c2s_unauthed", conntime = gettime() };
 	if true then
 		session.trace = newproxy(true);
 		getmetatable(session.trace).__gc = function () open_sessions = open_sessions - 1; print("Session got collected, now "..open_sessions.." sessions are allocated") end;
@@ -109,6 +113,8 @@
 	if session.resource then return nil, "cancel", "already-bound", "Cannot bind multiple resources on a single connection"; end
 	-- We don't support binding multiple resources
 
+	session.conntimetotal = gettime()-session.conntime;
+	
 	resource = resource or uuid_generate();
 	--FIXME: Randomly-generated resources must be unique per-user, and never conflict with existing
 	
@@ -175,7 +181,7 @@
 						
 						
 						local features = st.stanza("stream:features");
-						modulemanager.fire_event("stream-features", session, features);
+						fire_event("stream-features", session, features);
 						
 						send(features);
 						
--- a/prosody	Sat Dec 06 03:40:51 2008 +0000
+++ b/prosody	Sat Dec 06 03:41:49 2008 +0000
@@ -68,6 +68,44 @@
 	end
 end
 
+require "util.datamanager".set_data_path(data_path);
+
+local server = require "net.server"
+
+require "util.dependencies"
+
+-- Maps connections to sessions --
+sessions = {};
+hosts = {};
+
+
+-- Load and initialise core modules --
+
+require "util.import"
+require "core.xmlhandlers"
+require "core.rostermanager"
+require "core.offlinemessage"
+require "core.eventmanager"
+require "core.hostmanager"
+require "core.modulemanager"
+require "core.usermanager"
+require "core.sessionmanager"
+require "core.stanza_router"
+
+--[[
+pcall(require, "remdebug.engine");
+if remdebug then remdebug.engine.start() end
+]]
+
+local cl = require "net.connlisteners";
+
+require "util.stanza"
+require "util.jid"
+
+------------------------------------------------------------------------
+
+------------- Begin code without a home ---------------------
+
 local data_path = config.get("*", "core", "data_path") or CFG_DATADIR or "data";
 local path_separator = "/"; if os.getenv("WINDIR") then path_separator = "\\" end
 local _mkdir = {}
@@ -91,46 +129,11 @@
 end
 mkdir(data_path);
 
-require "util.datamanager".set_data_path(data_path);
-
-local server = require "net.server"
-
-require "util.dependencies"
-
--- Maps connections to sessions --
-sessions = {};
-hosts = {};
-
-local defined_hosts = config.getconfig();
-
-for host, host_config in pairs(defined_hosts) do
-	if host ~= "*" and (host_config.core.enabled == nil or host_config.core.enabled) then
-		hosts[host] = {type = "local", connected = true, sessions = {}, host = host, s2sout = {} };
-		mkdirs(host);
-	end
-end
+eventmanager.add_event_hook("host-activated", mkdirs);
 
--- Load and initialise core modules --
-
-require "util.import"
-require "core.xmlhandlers"
-require "core.rostermanager"
-require "core.offlinemessage"
-require "core.modulemanager"
-require "core.usermanager"
-require "core.sessionmanager"
-require "core.stanza_router"
+----------- End of out-of-place code --------------
 
---[[
-pcall(require, "remdebug.engine");
-if remdebug then remdebug.engine.start() end
-]]
-
-local start = require "net.connlisteners".start;
-require "util.stanza"
-require "util.jid"
-
-------------------------------------------------------------------------
+eventmanager.fire_event("server-starting");
 
 -- Initialise modules
 
@@ -159,13 +162,17 @@
 end
 
 -- start listening on sockets
-start("xmppclient", { ssl = global_ssl_ctx })
-start("xmppserver", { ssl = global_ssl_ctx })
+cl.start("xmppclient", { ssl = global_ssl_ctx })
+cl.start("xmppserver", { ssl = global_ssl_ctx })
 
 if config.get("*", "core", "console_enabled") then
-	start("console")
+	if cl.get("console") then
+		cl.start("console")
+	else
+		log("error", "Console is enabled, but the console module appears not to be loaded");
+	end
 end
 
-modulemanager.fire_event("server-started");
+eventmanager.fire_event("server-started");
 
 server.loop();
--- a/tests/test.lua	Sat Dec 06 03:40:51 2008 +0000
+++ b/tests/test.lua	Sat Dec 06 03:41:49 2008 +0000
@@ -21,6 +21,7 @@
 
 function run_all_tests()
 	dotest "util.jid"
+	dotest "util.multitable"
 	dotest "core.stanza_router"
 	dotest "core.s2smanager"
 	dotest "core.configmanager"
@@ -40,14 +41,34 @@
 	return setmetatable(t or {}, env_mt);
 end
 
-function assert_equal(a, b, message)
+function assert_equal(a, b, message, level)
 	if not (a == b) then
-		error("\n   assert_equal failed: "..tostring(a).." ~= "..tostring(b)..(message and ("\n   Message: "..message) or ""), 2);
+		error("\n   assert_equal failed: "..tostring(a).." ~= "..tostring(b)..(message and ("\n   Message: "..message) or ""), (level or 1) + 1);
 	elseif verbosity >= 4 then
 		print("assert_equal succeeded: "..tostring(a).." == "..tostring(b));
 	end
 end
 
+function assert_table(a, message, level)
+	assert_equal(type(a), "table", message, (level or 1) + 1);
+end
+function assert_function(a, message, level)
+	assert_equal(type(a), "function", message, (level or 1) + 1);
+end
+function assert_string(a, message, level)
+	assert_equal(type(a), "string", message, (level or 1) + 1);
+end
+function assert_boolean(a, message)
+	assert_equal(type(a), "boolean", message);
+end
+function assert_is(a, message)
+	assert_equal(not not a, true, message);
+end
+function assert_is_not(a, message)
+	assert_equal(not not a, false, message);
+end
+
+
 function dosingletest(testname, fname)
 	local tests = setmetatable({}, { __index = _G });
 	tests.__unit = testname;