mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
Use monitors to track muc rooms
This should prevent keeping rooms that were hard killed from in online table.
This commit is contained in:
parent
7209486386
commit
ca5d5f3b4c
@ -42,6 +42,7 @@
|
|||||||
store_room/5,
|
store_room/5,
|
||||||
restore_room/3,
|
restore_room/3,
|
||||||
forget_room/3,
|
forget_room/3,
|
||||||
|
create_room/3,
|
||||||
create_room/5,
|
create_room/5,
|
||||||
shutdown_rooms/1,
|
shutdown_rooms/1,
|
||||||
process_disco_info/1,
|
process_disco_info/1,
|
||||||
@ -99,6 +100,7 @@
|
|||||||
-callback register_online_room(binary(), binary(), binary(), pid()) -> any().
|
-callback register_online_room(binary(), binary(), binary(), pid()) -> any().
|
||||||
-callback unregister_online_room(binary(), binary(), binary(), pid()) -> any().
|
-callback unregister_online_room(binary(), binary(), binary(), pid()) -> any().
|
||||||
-callback find_online_room(binary(), binary(), binary()) -> {ok, pid()} | error.
|
-callback find_online_room(binary(), binary(), binary()) -> {ok, pid()} | error.
|
||||||
|
-callback find_online_room_by_pid(binary(), pid()) -> {ok, binary(), binary()} | error.
|
||||||
-callback get_online_rooms(binary(), binary(), undefined | rsm_set()) -> [{binary(), binary(), pid()}].
|
-callback get_online_rooms(binary(), binary(), undefined | rsm_set()) -> [{binary(), binary(), pid()}].
|
||||||
-callback count_online_rooms(binary(), binary()) -> non_neg_integer().
|
-callback count_online_rooms(binary(), binary()) -> non_neg_integer().
|
||||||
-callback rsm_supported() -> boolean().
|
-callback rsm_supported() -> boolean().
|
||||||
@ -295,6 +297,14 @@ create_room(Host, Name, From, Nick, Opts) ->
|
|||||||
Proc = procname(ServerHost, {Name, Host}),
|
Proc = procname(ServerHost, {Name, Host}),
|
||||||
?GEN_SERVER:call(Proc, {create, Name, Host, From, Nick, Opts}).
|
?GEN_SERVER:call(Proc, {create, Name, Host, From, Nick, Opts}).
|
||||||
|
|
||||||
|
%% @doc Create a room.
|
||||||
|
%% If Opts = default, the default room options are used.
|
||||||
|
%% Else use the passed options as defined in mod_muc_room.
|
||||||
|
create_room(Host, Name, Opts) ->
|
||||||
|
ServerHost = ejabberd_router:host_of_route(Host),
|
||||||
|
Proc = procname(ServerHost, {Name, Host}),
|
||||||
|
?GEN_SERVER:call(Proc, {create, Name, Host, Opts}).
|
||||||
|
|
||||||
store_room(ServerHost, Host, Name, Opts) ->
|
store_room(ServerHost, Host, Name, Opts) ->
|
||||||
store_room(ServerHost, Host, Name, Opts, undefined).
|
store_room(ServerHost, Host, Name, Opts, undefined).
|
||||||
|
|
||||||
@ -379,6 +389,25 @@ init([Host, Worker]) ->
|
|||||||
{stop, normal, ok, state()}.
|
{stop, normal, ok, state()}.
|
||||||
handle_call(stop, _From, State) ->
|
handle_call(stop, _From, State) ->
|
||||||
{stop, normal, ok, State};
|
{stop, normal, ok, State};
|
||||||
|
handle_call({unhibernate, Room, Host}, _From,
|
||||||
|
#{server_host := ServerHost} = State) ->
|
||||||
|
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
|
||||||
|
{reply, load_room(RMod, Host, ServerHost, Room), State};
|
||||||
|
handle_call({create, Room, Host, Opts}, _From,
|
||||||
|
#{server_host := ServerHost} = State) ->
|
||||||
|
?DEBUG("MUC: create new room '~ts'~n", [Room]),
|
||||||
|
NewOpts = case Opts of
|
||||||
|
default -> mod_muc_opt:default_room_options(ServerHost);
|
||||||
|
_ -> Opts
|
||||||
|
end,
|
||||||
|
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
|
||||||
|
case start_room(RMod, Host, ServerHost, Room, NewOpts) of
|
||||||
|
{ok, _} ->
|
||||||
|
ejabberd_hooks:run(create_room, ServerHost, [ServerHost, Room, Host]),
|
||||||
|
{reply, ok, State};
|
||||||
|
Err ->
|
||||||
|
{reply, Err, State}
|
||||||
|
end;
|
||||||
handle_call({create, Room, Host, From, Nick, Opts}, _From,
|
handle_call({create, Room, Host, From, Nick, Opts}, _From,
|
||||||
#{server_host := ServerHost} = State) ->
|
#{server_host := ServerHost} = State) ->
|
||||||
?DEBUG("MUC: create new room '~ts'~n", [Room]),
|
?DEBUG("MUC: create new room '~ts'~n", [Room]),
|
||||||
@ -437,6 +466,15 @@ handle_info({route, Packet}, #{server_host := ServerHost} = State) ->
|
|||||||
handle_info({room_destroyed, {Room, Host}, Pid}, State) ->
|
handle_info({room_destroyed, {Room, Host}, Pid}, State) ->
|
||||||
%% For backward compat
|
%% For backward compat
|
||||||
handle_cast({room_destroyed, {Room, Host}, Pid}, State);
|
handle_cast({room_destroyed, {Room, Host}, Pid}, State);
|
||||||
|
handle_info({'DOWN', _Ref, process, Pid, _Reason},
|
||||||
|
#{server_host := ServerHost} = State) ->
|
||||||
|
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
|
||||||
|
case RMod:find_online_room_by_pid(ServerHost, Pid) of
|
||||||
|
{ok, Room, Host} ->
|
||||||
|
handle_cast({room_destroyed, {Room, Host}, Pid}, State);
|
||||||
|
_ ->
|
||||||
|
{noreply, State}
|
||||||
|
end;
|
||||||
handle_info(Info, State) ->
|
handle_info(Info, State) ->
|
||||||
?ERROR_MSG("Unexpected info: ~p", [Info]),
|
?ERROR_MSG("Unexpected info: ~p", [Info]),
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
@ -531,7 +569,8 @@ unhibernate_room(ServerHost, Host, Room) ->
|
|||||||
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
|
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
|
||||||
case RMod:find_online_room(ServerHost, Room, Host) of
|
case RMod:find_online_room(ServerHost, Room, Host) of
|
||||||
error ->
|
error ->
|
||||||
case load_room(RMod, Host, ServerHost, Room) of
|
Proc = procname(ServerHost, {Room, Host}),
|
||||||
|
case ?GEN_SERVER:call(Proc, {unhibernate, Room, Host}) of
|
||||||
{ok, _} = R -> R;
|
{ok, _} = R -> R;
|
||||||
_ -> error
|
_ -> error
|
||||||
end;
|
end;
|
||||||
@ -791,25 +830,13 @@ get_rooms(ServerHost, Host) ->
|
|||||||
load_permanent_rooms(Hosts, ServerHost, Opts) ->
|
load_permanent_rooms(Hosts, ServerHost, Opts) ->
|
||||||
case mod_muc_opt:preload_rooms(Opts) of
|
case mod_muc_opt:preload_rooms(Opts) of
|
||||||
true ->
|
true ->
|
||||||
Access = get_access(Opts),
|
|
||||||
HistorySize = mod_muc_opt:history_size(Opts),
|
|
||||||
QueueType = mod_muc_opt:queue_type(Opts),
|
|
||||||
RoomShaper = mod_muc_opt:room_shaper(Opts),
|
|
||||||
RMod = gen_mod:ram_db_mod(Opts, ?MODULE),
|
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(Host) ->
|
fun(Host) ->
|
||||||
?DEBUG("Loading rooms at ~ts", [Host]),
|
?DEBUG("Loading rooms at ~ts", [Host]),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(R) ->
|
fun(R) ->
|
||||||
{Room, _} = R#muc_room.name_host,
|
{Room, _} = R#muc_room.name_host,
|
||||||
case RMod:find_online_room(ServerHost, Room, Host) of
|
unhibernate_room(ServerHost, Host, Room)
|
||||||
error ->
|
|
||||||
start_room(RMod, Host, ServerHost, Access,
|
|
||||||
Room, HistorySize, RoomShaper,
|
|
||||||
R#muc_room.opts, QueueType);
|
|
||||||
{ok, _} ->
|
|
||||||
ok
|
|
||||||
end
|
|
||||||
end, get_rooms(ServerHost, Host))
|
end, get_rooms(ServerHost, Host))
|
||||||
end, Hosts);
|
end, Hosts);
|
||||||
false ->
|
false ->
|
||||||
@ -877,6 +904,7 @@ start_room(Mod, Host, ServerHost, Access, Room,
|
|||||||
case mod_muc_room:start(Host, ServerHost, Access, Room,
|
case mod_muc_room:start(Host, ServerHost, Access, Room,
|
||||||
HistorySize, RoomShaper, DefOpts, QueueType) of
|
HistorySize, RoomShaper, DefOpts, QueueType) of
|
||||||
{ok, Pid} ->
|
{ok, Pid} ->
|
||||||
|
erlang:monitor(process, Pid),
|
||||||
Mod:register_online_room(ServerHost, Room, Host, Pid),
|
Mod:register_online_room(ServerHost, Room, Host, Pid),
|
||||||
{ok, Pid};
|
{ok, Pid};
|
||||||
Err ->
|
Err ->
|
||||||
@ -889,6 +917,7 @@ start_room(Mod, Host, ServerHost, Access, Room, HistorySize,
|
|||||||
HistorySize, RoomShaper,
|
HistorySize, RoomShaper,
|
||||||
Creator, Nick, DefOpts, QueueType) of
|
Creator, Nick, DefOpts, QueueType) of
|
||||||
{ok, Pid} ->
|
{ok, Pid} ->
|
||||||
|
erlang:monitor(process, Pid),
|
||||||
Mod:register_online_room(ServerHost, Room, Host, Pid),
|
Mod:register_online_room(ServerHost, Room, Host, Pid),
|
||||||
{ok, Pid};
|
{ok, Pid};
|
||||||
Err ->
|
Err ->
|
||||||
|
@ -653,6 +653,8 @@ create_room_with_opts(Name1, Host1, ServerHost1, CustomRoomOpts) ->
|
|||||||
{_, _, error} ->
|
{_, _, error} ->
|
||||||
throw({error, "Invalid 'serverhost'"});
|
throw({error, "Invalid 'serverhost'"});
|
||||||
{Name, Host, ServerHost} ->
|
{Name, Host, ServerHost} ->
|
||||||
|
case get_room_pid(Name, Host) of
|
||||||
|
room_not_found ->
|
||||||
%% Get the default room options from the muc configuration
|
%% Get the default room options from the muc configuration
|
||||||
DefRoomOpts = mod_muc_opt:default_room_options(ServerHost),
|
DefRoomOpts = mod_muc_opt:default_room_options(ServerHost),
|
||||||
%% Change default room options as required
|
%% Change default room options as required
|
||||||
@ -660,40 +662,12 @@ create_room_with_opts(Name1, Host1, ServerHost1, CustomRoomOpts) ->
|
|||||||
RoomOpts = lists:ukeymerge(1,
|
RoomOpts = lists:ukeymerge(1,
|
||||||
lists:keysort(1, FormattedRoomOpts),
|
lists:keysort(1, FormattedRoomOpts),
|
||||||
lists:keysort(1, DefRoomOpts)),
|
lists:keysort(1, DefRoomOpts)),
|
||||||
|
case mod_muc:create_room(Host, Name, RoomOpts) of
|
||||||
|
ok ->
|
||||||
%% Get all remaining mod_muc parameters that might be utilized
|
|
||||||
Access = mod_muc_opt:access(ServerHost),
|
|
||||||
AcCreate = mod_muc_opt:access_create(ServerHost),
|
|
||||||
AcAdmin = mod_muc_opt:access_admin(ServerHost),
|
|
||||||
AcPer = mod_muc_opt:access_persistent(ServerHost),
|
|
||||||
AcMam = mod_muc_opt:access_mam(ServerHost),
|
|
||||||
HistorySize = mod_muc_opt:history_size(ServerHost),
|
|
||||||
RoomShaper = mod_muc_opt:room_shaper(ServerHost),
|
|
||||||
QueueType = mod_muc_opt:queue_type(ServerHost),
|
|
||||||
|
|
||||||
%% If the room does not exist yet in the muc_online_room
|
|
||||||
case get_room_pid(Name, Host) of
|
|
||||||
room_not_found ->
|
|
||||||
%% Store the room on the server, it is not started yet though at this point
|
|
||||||
case lists:keyfind(persistent, 1, RoomOpts) of
|
|
||||||
{persistent, true} ->
|
|
||||||
mod_muc:store_room(ServerHost, Host, Name, RoomOpts);
|
|
||||||
_ ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
%% Start the room
|
|
||||||
{ok, Pid} = mod_muc_room:start(
|
|
||||||
Host,
|
|
||||||
ServerHost,
|
|
||||||
{Access, AcCreate, AcAdmin, AcPer, AcMam},
|
|
||||||
Name,
|
|
||||||
HistorySize,
|
|
||||||
RoomShaper,
|
|
||||||
RoomOpts,
|
|
||||||
QueueType),
|
|
||||||
mod_muc:register_online_room(Name, Host, Pid),
|
|
||||||
ok;
|
ok;
|
||||||
|
{error, _} ->
|
||||||
|
throw({error, "Unable to start room"})
|
||||||
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
throw({error, "Room already exists"})
|
throw({error, "Room already exists"})
|
||||||
end
|
end
|
||||||
|
@ -33,7 +33,8 @@
|
|||||||
-export([register_online_room/4, unregister_online_room/4, find_online_room/3,
|
-export([register_online_room/4, unregister_online_room/4, find_online_room/3,
|
||||||
get_online_rooms/3, count_online_rooms/2, rsm_supported/0,
|
get_online_rooms/3, count_online_rooms/2, rsm_supported/0,
|
||||||
register_online_user/4, unregister_online_user/4,
|
register_online_user/4, unregister_online_user/4,
|
||||||
count_online_rooms_by_user/3, get_online_rooms_by_user/3]).
|
count_online_rooms_by_user/3, get_online_rooms_by_user/3,
|
||||||
|
find_online_room_by_pid/2]).
|
||||||
-export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
|
-export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
|
||||||
get_affiliations/3, search_affiliation/4]).
|
get_affiliations/3, search_affiliation/4]).
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
@ -181,6 +182,19 @@ find_online_room(Room, Host) ->
|
|||||||
[#muc_online_room{pid = Pid}] -> {ok, Pid}
|
[#muc_online_room{pid = Pid}] -> {ok, Pid}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
find_online_room_by_pid(_ServerHost, Pid) ->
|
||||||
|
Res =
|
||||||
|
mnesia:dirty_select(
|
||||||
|
muc_online_room,
|
||||||
|
ets:fun2ms(
|
||||||
|
fun(#muc_online_room{name_host = {Name, Host}, pid = PidS})
|
||||||
|
when PidS == Pid -> {Name, Host}
|
||||||
|
end)),
|
||||||
|
case Res of
|
||||||
|
[{Name, Host}] -> {ok, Name, Host};
|
||||||
|
_ -> error
|
||||||
|
end.
|
||||||
|
|
||||||
count_online_rooms(_ServerHost, Host) ->
|
count_online_rooms(_ServerHost, Host) ->
|
||||||
ets:select_count(
|
ets:select_count(
|
||||||
muc_online_room,
|
muc_online_room,
|
||||||
|
@ -913,11 +913,9 @@ terminate(Reason, _StateName,
|
|||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
end,
|
end
|
||||||
mod_muc:room_destroyed(Host, Room, self(), LServer)
|
|
||||||
catch ?EX_RULE(E, R, St) ->
|
catch ?EX_RULE(E, R, St) ->
|
||||||
StackTrace = ?EX_STACK(St),
|
StackTrace = ?EX_STACK(St),
|
||||||
mod_muc:room_destroyed(Host, Room, self(), LServer),
|
|
||||||
?ERROR_MSG("Got exception on room termination:~n** ~ts",
|
?ERROR_MSG("Got exception on room termination:~n** ~ts",
|
||||||
[misc:format_exception(2, E, R, StackTrace)])
|
[misc:format_exception(2, E, R, StackTrace)])
|
||||||
end.
|
end.
|
||||||
|
@ -36,7 +36,8 @@
|
|||||||
get_online_rooms/3, count_online_rooms/2, rsm_supported/0,
|
get_online_rooms/3, count_online_rooms/2, rsm_supported/0,
|
||||||
register_online_user/4, unregister_online_user/4,
|
register_online_user/4, unregister_online_user/4,
|
||||||
count_online_rooms_by_user/3, get_online_rooms_by_user/3,
|
count_online_rooms_by_user/3, get_online_rooms_by_user/3,
|
||||||
get_subscribed_rooms/3, get_rooms_without_subscribers/2]).
|
get_subscribed_rooms/3, get_rooms_without_subscribers/2,
|
||||||
|
find_online_room_by_pid/2]).
|
||||||
-export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
|
-export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
|
||||||
get_affiliations/3, search_affiliation/4]).
|
get_affiliations/3, search_affiliation/4]).
|
||||||
|
|
||||||
@ -306,6 +307,21 @@ find_online_room(ServerHost, Room, Host) ->
|
|||||||
error
|
error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
find_online_room_by_pid(ServerHost, Pid) ->
|
||||||
|
PidS = misc:encode_pid(Pid),
|
||||||
|
NodeS = erlang:atom_to_binary(node(Pid), latin1),
|
||||||
|
case ejabberd_sql:sql_query(
|
||||||
|
ServerHost,
|
||||||
|
?SQL("select @(name)s, @(host)s from muc_online_room where "
|
||||||
|
"node=%(NodeS)s and pid=%(PidS)s")) of
|
||||||
|
{selected, [{Room, Host}]} ->
|
||||||
|
{ok, Room, Host};
|
||||||
|
{selected, []} ->
|
||||||
|
error;
|
||||||
|
_Err ->
|
||||||
|
error
|
||||||
|
end.
|
||||||
|
|
||||||
count_online_rooms(ServerHost, Host) ->
|
count_online_rooms(ServerHost, Host) ->
|
||||||
case ejabberd_sql:sql_query(
|
case ejabberd_sql:sql_query(
|
||||||
ServerHost,
|
ServerHost,
|
||||||
|
Loading…
Reference in New Issue
Block a user