changeset 162:fe9c4daee076

mod_throttle_presence: Buffer up presence for up to flush_presence_seconds and send latest presence stanzas for each contact at once
author Matthew Wild <mwild1@gmail.com>
date Thu, 03 Jun 2010 03:02:33 +0100
parents fda7faee7677
children 9fe6d314fd07
files mod_throttle_presence/mod_throttle_presence.lua
diffstat 1 files changed, 37 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_throttle_presence/mod_throttle_presence.lua	Thu Jun 03 03:02:33 2010 +0100
@@ -0,0 +1,37 @@
+local add_filter = require "util.filters".add_filter;
+local add_task = require "util.timer".add_task;
+
+local buffer_seconds = module:get_option_number("flush_presence_seconds");
+
+local function throttle_session(data)
+	local session = data.session;
+	local buffer, flushing = {}, false;
+	local timer_active = false;
+	local function flush_buffer()
+		module:log("debug", "Flushing buffer for %s", session.full_jid);
+		flushing = true;
+		for jid, presence in pairs(buffer) do
+			session.send(presence);
+		end
+		flushing = false;
+	end
+	local function throttle_presence(stanza)
+		if stanza.name ~= "presence" or (stanza.attr.type and stanza.attr.type ~= "unavailable") then
+			module:log("debug", "Non-presence stanza for %s: %s", session.full_jid, tostring(stanza));
+			flush_buffer();
+		elseif not flushing then
+			module:log("debug", "Buffering presence stanza from %s to %s", stanza.attr.from, session.full_jid);
+			buffer[stanza.attr.from] = stanza;
+			if not timer_active and buffer_seconds then
+				timer_active = true;
+				add_task(buffer_seconds, flush_buffer);
+			end
+			return nil; -- Drop this stanza (we've stored it for later)
+		end
+		return stanza;
+	end
+	add_filter(session, "stanzas/out", throttle_presence);
+end
+
+
+module:hook("resource-bind", throttle_session);