From: Badlop Date: Mon, 15 Feb 2010 22:34:33 +0000 (+0100) Subject: Rewrite mnesia counter functions to use dirty_update_counter (EJAB-1177) X-Git-Tag: v2.1.3~41 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=47ee65d101cb68c130326ac8fab0f4a3f240269b;p=ejabberd Rewrite mnesia counter functions to use dirty_update_counter (EJAB-1177) (thanks to Juan Pablo Carlino and Alexey Shchepin) --- diff --git a/src/ejabberd_auth_internal.erl b/src/ejabberd_auth_internal.erl index 5619679fd..9cd89b724 100644 --- a/src/ejabberd_auth_internal.erl +++ b/src/ejabberd_auth_internal.erl @@ -68,7 +68,11 @@ update_reg_users_counter_table(Server) -> Set = get_vh_registered_users(Server), Size = length(Set), LServer = jlib:nameprep(Server), - set_vh_registered_users_counter(LServer, Size). + F = fun() -> + mnesia:write(#reg_users_counter{vhost = LServer, + count = Size}) + end, + mnesia:sync_dirty(F). plain_password_required() -> false. @@ -137,7 +141,9 @@ try_register(User, Server, Password) -> [] -> mnesia:write(#passwd{us = US, password = Password}), - inc_vh_registered_users_counter(LServer), + mnesia:dirty_update_counter( + reg_users_counter, + LServer, 1), ok; [_E] -> exists @@ -224,40 +230,6 @@ get_vh_registered_users_number(Server, [{prefix, Prefix}]) when is_list(Prefix) get_vh_registered_users_number(Server, _) -> get_vh_registered_users_number(Server). -inc_vh_registered_users_counter(LServer) -> - F = fun() -> - case mnesia:wread({reg_users_counter, LServer}) of - [C] -> - Count = C#reg_users_counter.count + 1, - C2 = C#reg_users_counter{count = Count}, - mnesia:write(C2); - _ -> - mnesia:write(#reg_users_counter{vhost = LServer, - count = 1}) - end - end, - mnesia:sync_dirty(F). - -dec_vh_registered_users_counter(LServer) -> - F = fun() -> - case mnesia:wread({reg_users_counter, LServer}) of - [C] -> - Count = C#reg_users_counter.count - 1, - C2 = C#reg_users_counter{count = Count}, - mnesia:write(C2); - _ -> - error - end - end, - mnesia:sync_dirty(F). - -set_vh_registered_users_counter(LServer, Count) -> - F = fun() -> - mnesia:write(#reg_users_counter{vhost = LServer, - count = Count}) - end, - mnesia:sync_dirty(F). - get_password(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), @@ -303,7 +275,8 @@ remove_user(User, Server) -> US = {LUser, LServer}, F = fun() -> mnesia:delete({passwd, US}), - dec_vh_registered_users_counter(LServer) + mnesia:dirty_update_counter(reg_users_counter, + LServer, -1) end, mnesia:transaction(F), ok. @@ -318,7 +291,8 @@ remove_user(User, Server, Password) -> case mnesia:read({passwd, US}) of [#passwd{password = Password}] -> mnesia:delete({passwd, US}), - dec_vh_registered_users_counter(LServer), + mnesia:dirty_update_counter(reg_users_counter, + LServer, -1), ok; [_] -> not_allowed; diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index bba4a7376..296400f84 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -92,7 +92,8 @@ route(From, To, Packet) -> open_session(SID, User, Server, Resource, Info) -> set_session(SID, User, Server, Resource, undefined, Info), - inc_session_counter(jlib:nameprep(Server)), + mnesia:dirty_update_counter(session_counter, + jlib:nameprep(Server), 1), check_for_sessions_to_replace(User, Server, Resource), JID = jlib:make_jid(User, Server, Resource), ejabberd_hooks:run(sm_register_connection_hook, JID#jid.lserver, @@ -105,7 +106,8 @@ close_session(SID, User, Server, Resource) -> end, F = fun() -> mnesia:delete({session, SID}), - dec_session_counter(jlib:nameprep(Server)) + mnesia:dirty_update_counter(session_counter, + jlib:nameprep(Server), -1) end, mnesia:sync_dirty(F), JID = jlib:make_jid(User, Server, Resource), @@ -263,6 +265,7 @@ init([]) -> mnesia:add_table_index(session, usr), mnesia:add_table_index(session, us), mnesia:add_table_copy(session, node(), ram_copies), + mnesia:add_table_copy(session_counter, node(), ram_copies), mnesia:subscribe(system), ets:new(sm_iqtable, [named_table]), lists:foreach( @@ -316,7 +319,7 @@ handle_info({route, From, To, Packet}, State) -> end, {noreply, State}; handle_info({mnesia_system_event, {mnesia_down, Node}}, State) -> - clean_table_from_bad_node(Node), + recount_session_table(Node), {noreply, State}; handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) -> ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function}), @@ -373,7 +376,9 @@ set_session(SID, User, Server, Resource, Priority, Info) -> end, mnesia:sync_dirty(F). -clean_table_from_bad_node(Node) -> +%% Recalculates alive sessions when Node goes down +%% and updates session and session_counter tables +recount_session_table(Node) -> F = fun() -> Es = mnesia:select( session, @@ -381,12 +386,22 @@ clean_table_from_bad_node(Node) -> [{'==', {node, '$1'}, Node}], ['$_']}]), lists:foreach(fun(E) -> - {_, LServer} = E#session.us, - dec_session_counter(LServer), mnesia:delete({session, E#session.sid}) - end, Es) + end, Es), + %% reset session_counter table with active sessions + mnesia:clear_table(session_counter), + lists:foreach(fun(Server) -> + LServer = jlib:nameprep(Server), + Hs = mnesia:select(session, + [{#session{usr = '$1', _ = '_'}, + [{'==', {element, 2, '$1'}, LServer}], + ['$1']}]), + mnesia:write( + #session_counter{vhost = LServer, + count = length(Hs)}) + end, ?MYHOSTS) end, - mnesia:sync_dirty(F). + mnesia:async_dirty(F). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -663,34 +678,6 @@ get_max_user_sessions(LUser, Host) -> _ -> ?MAX_USER_SESSIONS end. -inc_session_counter(LServer) -> - F = fun() -> - case mnesia:wread({session_counter, LServer}) of - [C] -> - Count = C#session_counter.count + 1, - C2 = C#session_counter{count = Count}, - mnesia:write(C2); - _ -> - mnesia:write(#session_counter{vhost = LServer, - count = 1}) - end - end, - mnesia:sync_dirty(F). - -dec_session_counter(LServer) -> - F = fun() -> - case mnesia:wread({session_counter, LServer}) of - [C] -> - Count = C#session_counter.count - 1, - C2 = C#session_counter{count = Count}, - mnesia:write(C2); - _ -> - error - end - end, - mnesia:sync_dirty(F). - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% process_iq(From, To, Packet) ->