Software /
code /
prosody-modules
Changeset
2155:f24b02e0d706
mod_presence_dedup: Attempt at saving bandwith by deduplicating presence stanzas
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 03 Apr 2016 17:09:03 +0200 |
parents | 2154:ada71b81425a |
children | 2156:3fcac143fe0b 2159:5e8dec076afc |
files | mod_presence_dedup/README.markdown mod_presence_dedup/mod_presence_dedup.lua |
diffstat | 2 files changed, 62 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_presence_dedup/README.markdown Sun Apr 03 17:09:03 2016 +0200 @@ -0,0 +1,18 @@ +--- +summary: Presence deduplication module +... + +This module tries to squash incoming identical presence stanzas to save +some bandwith at the cost of increased memory use. + +Configuration +============= + + Option Type Default + ------------------------------ -------- --------- + presence\_dedup\_cache\_size number `100` + +The only setting controls how many presence stanzas *per session* are +kept in memory for comparing with incoming presenece. + +Requires Prosody 0.10 or later.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_presence_dedup/mod_presence_dedup.lua Sun Apr 03 17:09:03 2016 +0200 @@ -0,0 +1,44 @@ +local st = require "util.stanza"; +local cache = require "util.cache"; +local add_filter = require "util.filters".add_filter; + +local cache_size = module:get_option_number("presence_dedup_cache_size", 100); + +-- stanza equality tests +local function attr_eq(a, b) + if a == b then return true; end -- unlikely but not impossible + for k,v in pairs(a) do if b[k] ~= v then return false; end end + for k,v in pairs(b) do if a[k] ~= v then return false; end end + return true; +end + +local function st_eq(a, b) + if a == b then return true; end + if type(b) ~= "table" then return false; end + if getmetatable(b) ~= st.stanza_mt then return false; end + if a.name ~= b.name then return false; end + if #a ~= #b then return false; end + if not attr_eq(a.attr, b.attr) then return false; end + for i = 1, #a do if not st_eq(a[i], b[i]) then return false; end end + return true; +end + +local function dedup_presence(stanza, session) + if session.presence_cache and session.presence + and getmetatable(stanza) == st.stanza_mt and stanza.name == "presence" + and stanza.attr.xmlns == nil and stanza.attr.from then + local cached = session.presence_cache:get(stanza.attr.from); + if st_eq(stanza, cached) then + return nil; + else + session.presence_cache:set(stanza.attr.from, st.clone(stanza)); + end + end + return stanza; +end + +module:hook("presence/initial", function (event) + local session, stanza = event.origin, event.stanza; + session.presence_cache = cache.new(cache_size); + add_filter(session, "stanzas/out", dedup_presence, 90); +end);