diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 8ecdda0e8..8fe72881c 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -128,10 +128,8 @@ start(Host, Opts) -> stop(Host) -> Proc = mod_muc_sup:procname(Host), - Rooms = shutdown_rooms(Host), supervisor:terminate_child(ejabberd_gen_mod_sup, Proc), - supervisor:delete_child(ejabberd_gen_mod_sup, Proc), - {wait, Rooms}. + supervisor:delete_child(ejabberd_gen_mod_sup, Proc). -spec reload(binary(), gen_mod:opts(), gen_mod:opts()) -> ok. reload(ServerHost, NewOpts, OldOpts) -> @@ -517,7 +515,7 @@ route_to_room(Packet, ServerHost) -> ejabberd_router:route_error(Packet, Err); StartType -> case load_room(RMod, Host, ServerHost, Room) of - error when StartType == start -> + {error, notfound} when StartType == start -> case check_create_room(ServerHost, Host, Room, From) of true -> case start_new_room(RMod, Host, ServerHost, Room, From, Nick) of @@ -533,11 +531,14 @@ route_to_room(Packet, ServerHost) -> Err = xmpp:err_forbidden(ErrText, Lang), ejabberd_router:route_error(Packet, Err) end; - error -> + {error, notfound} -> Lang = xmpp:get_lang(Packet), ErrText = ?T("Conference room does not exist"), Err = xmpp:err_item_not_found(ErrText, Lang), ejabberd_router:route_error(Packet, Err); + {error, _} -> + Err = xmpp:err_internal_server_error(), + ejabberd_router:route_error(Packet, Err); {ok, Pid2} -> mod_muc_room:route(Pid2, Packet) end @@ -774,17 +775,19 @@ load_permanent_rooms(Hosts, ServerHost, Opts) -> ok end. +-spec load_room(module(), binary(), binary(), binary()) -> {ok, pid()} | + {error, notfound | term()}. load_room(RMod, Host, ServerHost, Room) -> case restore_room(ServerHost, Host, Room) of error -> - error; + {error, notfound}; Opts0 -> case proplists:get_bool(persistent, Opts0) of true -> ?DEBUG("Restore room: ~s", [Room]), start_room(RMod, Host, ServerHost, Room, Opts0); _ -> - error + {error, notfound} end end. diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 2f1ec1957..af7e3c3bd 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -34,6 +34,7 @@ start_link/8, start/10, start/8, + supervisor/1, get_role/2, get_affiliation/2, is_occupant_or_admin/2, @@ -113,17 +114,19 @@ {ok, pid()} | {error, any()}. start(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, Nick, DefRoomOpts, QueueType) -> - p1_fsm:start(?MODULE, [Host, ServerHost, Access, Room, HistorySize, - RoomShaper, Creator, Nick, DefRoomOpts, QueueType], - ?FSMOPTS). + supervisor:start_child( + supervisor(ServerHost), + [Host, ServerHost, Access, Room, HistorySize, + RoomShaper, Creator, Nick, DefRoomOpts, QueueType]). -spec start(binary(), binary(), mod_muc:access(), binary(), non_neg_integer(), atom(), [{atom(), term()}], ram | file) -> {ok, pid()} | {error, any()}. start(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, QueueType) -> - p1_fsm:start(?MODULE, [Host, ServerHost, Access, Room, HistorySize, - RoomShaper, Opts, QueueType], - ?FSMOPTS). + supervisor:start_child( + supervisor(ServerHost), + [Host, ServerHost, Access, Room, HistorySize, + RoomShaper, Opts, QueueType]). -spec start_link(binary(), binary(), mod_muc:access(), binary(), non_neg_integer(), atom(), jid(), binary(), [{atom(), term()}], ram | file) -> @@ -142,6 +145,10 @@ start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, QueueT RoomShaper, Opts, QueueType], ?FSMOPTS). +-spec supervisor(binary()) -> atom(). +supervisor(Host) -> + gen_mod:get_module_proc(Host, mod_muc_room_sup). + -spec destroy(pid()) -> ok. destroy(Pid) -> p1_fsm:send_all_state_event(Pid, destroy). diff --git a/src/mod_muc_sup.erl b/src/mod_muc_sup.erl index c2b4a7240..0e5e75cb8 100644 --- a/src/mod_muc_sup.erl +++ b/src/mod_muc_sup.erl @@ -52,15 +52,26 @@ procname(Host) -> %%%=================================================================== init([Host, Opts]) -> Cores = erlang:system_info(logical_processors), - Specs = [#{id => mod_muc:procname(Host, I), - start => {mod_muc, start_link, [Host, Opts, I]}, - restart => permanent, - shutdown => timer:minutes(1), - type => worker, - modules => [mod_muc]} - || I <- lists:seq(1, Cores)], + Specs = lists:foldl( + fun(I, Acc) -> + [#{id => mod_muc:procname(Host, I), + start => {mod_muc, start_link, [Host, Opts, I]}, + restart => permanent, + shutdown => timer:minutes(1), + type => worker, + modules => [mod_muc]}|Acc] + end, [room_sup_spec(Host)], lists:seq(1, Cores)), {ok, {{one_for_one, 10*Cores, 1}, Specs}}. %%%=================================================================== %%% Internal functions %%%=================================================================== +-spec room_sup_spec(binary()) -> supervisor:child_spec(). +room_sup_spec(Host) -> + Name = mod_muc_room:supervisor(Host), + #{id => Name, + start => {ejabberd_tmp_sup, start_link, [Name, mod_muc_room]}, + restart => permanent, + shutdown => infinity, + type => supervisor, + modules => [ejabberd_tmp_sup]}.