Mercurial > prosody-modules
comparison mod_presence_dedup/mod_presence_dedup.lua @ 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 | |
children | 19924a2c4a48 |
comparison
equal
deleted
inserted
replaced
2154:ada71b81425a | 2155:f24b02e0d706 |
---|---|
1 local st = require "util.stanza"; | |
2 local cache = require "util.cache"; | |
3 local add_filter = require "util.filters".add_filter; | |
4 | |
5 local cache_size = module:get_option_number("presence_dedup_cache_size", 100); | |
6 | |
7 -- stanza equality tests | |
8 local function attr_eq(a, b) | |
9 if a == b then return true; end -- unlikely but not impossible | |
10 for k,v in pairs(a) do if b[k] ~= v then return false; end end | |
11 for k,v in pairs(b) do if a[k] ~= v then return false; end end | |
12 return true; | |
13 end | |
14 | |
15 local function st_eq(a, b) | |
16 if a == b then return true; end | |
17 if type(b) ~= "table" then return false; end | |
18 if getmetatable(b) ~= st.stanza_mt then return false; end | |
19 if a.name ~= b.name then return false; end | |
20 if #a ~= #b then return false; end | |
21 if not attr_eq(a.attr, b.attr) then return false; end | |
22 for i = 1, #a do if not st_eq(a[i], b[i]) then return false; end end | |
23 return true; | |
24 end | |
25 | |
26 local function dedup_presence(stanza, session) | |
27 if session.presence_cache and session.presence | |
28 and getmetatable(stanza) == st.stanza_mt and stanza.name == "presence" | |
29 and stanza.attr.xmlns == nil and stanza.attr.from then | |
30 local cached = session.presence_cache:get(stanza.attr.from); | |
31 if st_eq(stanza, cached) then | |
32 return nil; | |
33 else | |
34 session.presence_cache:set(stanza.attr.from, st.clone(stanza)); | |
35 end | |
36 end | |
37 return stanza; | |
38 end | |
39 | |
40 module:hook("presence/initial", function (event) | |
41 local session, stanza = event.origin, event.stanza; | |
42 session.presence_cache = cache.new(cache_size); | |
43 add_filter(session, "stanzas/out", dedup_presence, 90); | |
44 end); |