From 31f6a9e66e48c8045ee5cfe96345cfa86e0cc202 Mon Sep 17 00:00:00 2001 From: Pablo Polvorin Date: Thu, 10 Nov 2011 12:54:11 -0300 Subject: [PATCH] Add command to persist recent MUC messages (EJABS-1785) Example: $ejabberdctl persist_recent_messages Host 'localhost' , 4 messages persisted in 12 rooms --- src/ejabberd_admin.erl | 16 ++++++++++++++-- src/mod_muc/mod_muc.erl | 15 ++++++++++++++- src/mod_muc/mod_muc_room.erl | 13 ++++++++++--- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/ejabberd_admin.erl b/src/ejabberd_admin.erl index 3237d9c95..629b1d8c5 100644 --- a/src/ejabberd_admin.erl +++ b/src/ejabberd_admin.erl @@ -49,7 +49,8 @@ dump_to_textfile/1, dump_to_textfile/2, mnesia_change_nodename/4, restore/1, % Still used by some modules - moderate_room_history/2 + moderate_room_history/2, + persist_recent_messages/0 ]). -include("ejabberd.hrl"). @@ -210,6 +211,11 @@ commands() -> module = ?MODULE, function = moderate_room_history, args = [{room, string}, {nick, string}], result = {res, restuple}} + #ejabberd_commands{name = persist_recent_messages, tags = [server], + desc = "Force recent muc messages to be savd on DB", + module = ?MODULE, function = persist_recent_messages, + args = [], + result = {res, restuple}} ]. %%% @@ -225,8 +231,14 @@ moderate_room_history(Room, Nick) -> _ -> io_lib:format("Bad nodes: ~p", [BadNodes]) end, - {ok, io:format("Deleted: ~p ~s", [Res, B])}. + {ok, io_lib:format("Deleted: ~p ~s", [Res, B])}. +persist_recent_messages() -> + Saved = [ {Host, mod_muc:persist_recent_messages(Host)} || Host <- ?MYHOSTS], + R = lists:map(fun({Host, {RoomsPersisted, Messages}}) -> + io_lib:format("Host '~s' , ~p messages persisted in ~p rooms\n", [Host, Messages, RoomsPersisted]) + end, Saved), + {ok,io_lib:format("~s", [R])}. %%% %%% Server management diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl index 904d64c7a..813aa63e2 100644 --- a/src/mod_muc/mod_muc.erl +++ b/src/mod_muc/mod_muc.erl @@ -48,7 +48,8 @@ get_vh_rooms/1, is_broadcasted/1, can_use_nick/3, - moderate_room_history/2]). + moderate_room_history/2, + persist_recent_messages/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -114,6 +115,18 @@ shutdown_rooms(Host) -> [Pid ! 'shutdown' || Pid <- Rooms], Rooms. +%% Returns {RoomsPersisted, MessagesPersisted} +persist_recent_messages(Host) -> + MyHost = gen_mod:get_module_opt_host(Host, mod_muc, "conference.@HOST@"), + Rooms = mnesia:dirty_select(muc_online_room, + [{#muc_online_room{name_host = '$1', pid = '$2'}, + [{'==', {element, 2, '$1'}, MyHost}], + ['$2']}]), + lists:foldl(fun(Pid, {NRooms, Messages}) -> + case mod_muc_room:persist_recent_messages(Pid) of + {ok, {persisted, N}} -> {NRooms +1, Messages +N}; + {ok, not_persistent} -> {NRooms, Messages} + end end, {0, 0}, Rooms). moderate_room_history(RoomStr, Nick) -> Room = jlib:string_to_jid(RoomStr), diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl index 2867f06dc..b8a0697df 100644 --- a/src/mod_muc/mod_muc_room.erl +++ b/src/mod_muc/mod_muc_room.erl @@ -41,7 +41,8 @@ start/2, migrate/3, route/4, - moderate_room_history/2]). + moderate_room_history/2, + persist_recent_messages/1]). %% gen_fsm callbacks -export([init/1, @@ -116,6 +117,8 @@ migrate(FsmRef, Node, After) -> moderate_room_history(FsmRef, Nick) -> ?GEN_FSM:sync_send_all_state_event(FsmRef, {moderate_room_history, Nick}). +persist_recent_messages(FsmRef) -> + ?GEN_FSM:sync_send_all_state_event(FsmRef, persist_recent_messages). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- @@ -752,6 +755,9 @@ handle_sync_event({moderate_room_history, Nick}, _From, StateName, #state{histor Moderated = History#lqueue.len - NewHistory#lqueue.len, {reply, {ok, integer_to_list(Moderated)}, StateName, StateData#state{history = NewHistory}}; +handle_sync_event(persist_recent_messages, _From, StateName, StateData) -> + {reply, persist_muc_history(StateData), StateName, StateData}; + handle_sync_event({get_disco_item, JID, Lang}, _From, StateName, StateData) -> Reply = get_roomdesc_reply(JID, StateData, get_roomdesc_tail(StateData, Lang)), @@ -956,12 +962,13 @@ persist_muc_history(#state{room = Room, server_host = Server, config = #config{p integer_to_list(calendar:datetime_to_gregorian_seconds(Timestamp)), integer_to_list(Size)) end, lqueue_to_list(Q)), - odbc_queries:clear_and_add_roomhistory(Server,ejabberd_odbc:escape(Room), Queries); + odbc_queries:clear_and_add_roomhistory(Server,ejabberd_odbc:escape(Room), Queries), + {ok, {persisted, length(Queries)}}; %% en mod_muc, cuando se levantan los muc persistentes, si se crea, y el flag persist_history esta en true, %% se levantan los mensajes persistentes tb. persist_muc_history(_) -> - ok. + {ok, not_persistent}. route(Pid, From, ToNick, Packet) -> ?GEN_FSM:send_event(Pid, {route, From, ToNick, Packet}).