Software /
code /
prosody
Comparison
plugins/mod_muc_mam.lua @ 9880:78885b1bbb91 0.11
mod_muc_mam: Copy cleanup mechanism from mod_mam (fixes #672)
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 22 Mar 2019 17:40:07 +0100 |
parent | 9843:17060708d0eb |
child | 9882:18f025b3987d |
child | 10029:2c8f674b9243 |
comparison
equal
deleted
inserted
replaced
9879:ddc07fb8dcd4 | 9880:78885b1bbb91 |
---|---|
27 | 27 |
28 local is_stanza = st.is_stanza; | 28 local is_stanza = st.is_stanza; |
29 local tostring = tostring; | 29 local tostring = tostring; |
30 local time_now = os.time; | 30 local time_now = os.time; |
31 local m_min = math.min; | 31 local m_min = math.min; |
32 local timestamp, timestamp_parse = require "util.datetime".datetime, require "util.datetime".parse; | 32 local timestamp, timestamp_parse, datestamp = import( "util.datetime", "datetime", "parse", "date"); |
33 local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", 50); | 33 local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", 50); |
34 | 34 |
35 local default_history_length = 20; | 35 local default_history_length = 20; |
36 local max_history_length = module:get_option_number("max_history_messages", math.huge); | 36 local max_history_length = module:get_option_number("max_history_messages", math.huge); |
37 | 37 |
38 local function get_historylength(room) | 38 local function get_historylength(room) |
39 return math.min(room._data.history_length or default_history_length, max_history_length); | 39 return math.min(room._data.history_length or default_history_length, max_history_length); |
40 end | |
41 | |
42 function schedule_cleanup() | |
43 -- replaced by non-noop later if cleanup is enabled | |
40 end | 44 end |
41 | 45 |
42 local log_all_rooms = module:get_option_boolean("muc_log_all_rooms", false); | 46 local log_all_rooms = module:get_option_boolean("muc_log_all_rooms", false); |
43 local log_by_default = module:get_option_boolean("muc_log_by_default", true); | 47 local log_by_default = module:get_option_boolean("muc_log_by_default", true); |
44 | 48 |
349 | 353 |
350 -- And stash it | 354 -- And stash it |
351 local id = archive:append(room_node, nil, stored_stanza, time_now(), with); | 355 local id = archive:append(room_node, nil, stored_stanza, time_now(), with); |
352 | 356 |
353 if id then | 357 if id then |
358 schedule_cleanup(room_node); | |
354 stanza:add_direct_child(st.stanza("stanza-id", { xmlns = xmlns_st_id, by = self.jid, id = id })); | 359 stanza:add_direct_child(st.stanza("stanza-id", { xmlns = xmlns_st_id, by = self.jid, id = id })); |
355 end | 360 end |
356 end | 361 end |
357 | 362 |
358 module:hook("muc-add-history", function (event) | 363 module:hook("muc-add-history", function (event) |
384 module:add_feature(xmlns_mam); | 389 module:add_feature(xmlns_mam); |
385 | 390 |
386 module:hook("muc-disco#info", function(event) | 391 module:hook("muc-disco#info", function(event) |
387 event.reply:tag("feature", {var=xmlns_mam}):up(); | 392 event.reply:tag("feature", {var=xmlns_mam}):up(); |
388 end); | 393 end); |
394 | |
395 -- Cleanup | |
396 | |
397 local cleanup_after = module:get_option_string("muc_log_expires_after", "1w"); | |
398 local cleanup_interval = module:get_option_number("muc_log_cleanup_interval", 4 * 60 * 60); | |
399 | |
400 if cleanup_after ~= "never" then | |
401 local cleanup_storage = module:open_store("muc_log_cleanup"); | |
402 local cleanup_map = module:open_store("muc_log_cleanup", "map"); | |
403 | |
404 local day = 86400; | |
405 local multipliers = { d = day, w = day * 7, m = 31 * day, y = 365.2425 * day }; | |
406 local n, m = cleanup_after:lower():match("(%d+)%s*([dwmy]?)"); | |
407 if not n then | |
408 module:log("error", "Could not parse muc_log_expires_after string %q", cleanup_after); | |
409 return false; | |
410 end | |
411 | |
412 cleanup_after = tonumber(n) * ( multipliers[m] or 1 ); | |
413 | |
414 module:log("debug", "muc_log_expires_after = %d -- in seconds", cleanup_after); | |
415 | |
416 if not archive.delete then | |
417 module:log("error", "muc_log_expires_after set but mod_%s does not support deleting", archive._provided_by); | |
418 return false; | |
419 end | |
420 | |
421 -- For each day, store a set of rooms that have new messages. To expire | |
422 -- messages, we collect the union of sets of rooms from dates that fall | |
423 -- outside the cleanup range. | |
424 | |
425 function schedule_cleanup(roomname, date) | |
426 cleanup_map:set(date or datestamp(), roomname, true); | |
427 end | |
428 | |
429 cleanup_runner = require "util.async".runner(function () | |
430 local rooms = {}; | |
431 local cut_off = datestamp(os.time() - cleanup_after); | |
432 for date in cleanup_storage:users() do | |
433 if date <= cut_off then | |
434 module:log("debug", "Messages from %q should be expired", date); | |
435 local messages_this_day = cleanup_storage:get(date); | |
436 if messages_this_day then | |
437 for room in pairs(messages_this_day) do | |
438 rooms[room] = true; | |
439 end | |
440 if date < cut_off then | |
441 -- Messages from the same day as the cut-off might not have expired yet, | |
442 -- but all earlier will have, so clear storage for those days. | |
443 cleanup_storage:set(date, nil); | |
444 end | |
445 end | |
446 end | |
447 end | |
448 local sum, num_rooms = 0, 0; | |
449 for room in pairs(rooms) do | |
450 local ok, err = archive:delete(room, { ["end"] = os.time() - cleanup_after; }) | |
451 if ok then | |
452 num_rooms = num_rooms + 1; | |
453 sum = sum + (tonumber(ok) or 0); | |
454 end | |
455 end | |
456 module:log("info", "Deleted %d expired messages for %d rooms", sum, num_rooms); | |
457 end); | |
458 | |
459 cleanup_task = module:add_timer(1, function () | |
460 cleanup_runner:run(true); | |
461 return cleanup_interval; | |
462 end); | |
463 else | |
464 module:log("debug", "Archive expiry disabled"); | |
465 end |