24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-06-10 21:47:01 +02:00

Improve purge_offline filter and speed (#543)

This commit is contained in:
Christophe Romain 2015-04-22 18:11:39 +02:00
parent df3afafb48
commit 38dd44e18f

View File

@ -4268,63 +4268,78 @@ on_user_offline(_, JID, _) ->
_ -> true _ -> true
end. end.
purge_offline({User, Server, _} = LJID) -> purge_offline(LJID) ->
Host = host(element(2, LJID)), Host = host(element(2, LJID)),
Plugins = plugins(Host), Plugins = plugins(Host),
Result = lists:foldl(fun (Type, {Status, Acc}) -> Result = lists:foldl(fun (Type, {Status, Acc}) ->
Features = plugin_features(Host, Type),
case lists:member(<<"retrieve-affiliations">>, plugin_features(Host, Type)) of case lists:member(<<"retrieve-affiliations">>, plugin_features(Host, Type)) of
false -> false ->
{{error, {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED,
extended_error(?ERR_FEATURE_NOT_IMPLEMENTED,
unsupported, <<"retrieve-affiliations">>)}, unsupported, <<"retrieve-affiliations">>)},
Acc}; Acc};
true -> true ->
Items = lists:member(<<"retract-items">>, Features)
andalso lists:member(<<"persistent-items">>, Features),
if Items ->
{result, Affs} = node_action(Host, Type, {result, Affs} = node_action(Host, Type,
get_entity_affiliations, get_entity_affiliations, [Host, LJID]),
[Host, LJID]), {Status, [Affs | Acc]};
{Status, [Affs | Acc]} true ->
{Status, Acc}
end
end end
end, end,
{ok, []}, Plugins), {ok, []}, Plugins),
case Result of case Result of
{ok, Affs} -> {ok, Affs} ->
lists:foreach(fun lists:foreach(
({#pubsub_node{nodeid = {_, Node}, options = Options, type = Type}, Aff}) fun ({Node, Affiliation}) ->
when Aff == owner orelse Aff == publisher -> Options = Node#pubsub_node.options,
Action = fun (#pubsub_node{type = NType, id = Nidx}) -> Publisher = lists:member(Affiliation, [owner,publisher,publish_only]),
node_call(Host, NType, get_items, [Nidx, service_jid(Host), none]) Open = (get_option(Options, publish_model) == open),
end, Purge = (get_option(Options, purge_offline)
case transaction(Host, Node, Action, sync_dirty) of andalso get_option(Options, persist_items)),
{result, {_, {[], _}}} -> if (Publisher or Open) and Purge ->
true; purge_offline(Host, LJID, Node);
{result, {_, {Items, _}}} -> true ->
Features = plugin_features(Host, Type), ok
case {lists:member(<<"retract-items">>, Features), end
lists:member(<<"persistent-items">>, Features), end, lists:usort(lists:flatten(Affs)));
get_option(Options, persist_items), {Error, _} ->
get_option(Options, purge_offline)} ?DEBUG("on_user_offline ~p", [Error])
of end.
{true, true, true, true} ->
purge_offline(Host, LJID, Node) ->
Nidx = Node#pubsub_node.id,
Type = Node#pubsub_node.type,
Options = Node#pubsub_node.options,
case node_action(Host, Type, get_items, [Nidx, service_jid(Host), none]) of
{result, {[], _}} ->
ok;
{result, {Items, _}} ->
{User, Server, _} = LJID,
PublishModel = get_option(Options, publish_model),
ForceNotify = get_option(Options, notify_retract), ForceNotify = get_option(Options, notify_retract),
{_, NodeId} = Node#pubsub_node.nodeid,
lists:foreach(fun lists:foreach(fun
(#pubsub_item{itemid = {ItemId, _}, (#pubsub_item{itemid = {ItemId, _}, modification = {_, {U, S, _}}})
modification = {_, {U, S, _}}})
when (U == User) and (S == Server) -> when (U == User) and (S == Server) ->
delete_item(Host, Node, LJID, ItemId, ForceNotify); case node_action(Host, Type, delete_item, [Nidx, {U, S, <<>>}, PublishModel, ItemId]) of
(_) -> {result, {_, broadcast}} ->
true broadcast_retract_items(Host, NodeId, Nidx, Type, Options, [ItemId], ForceNotify),
end, case get_cached_item(Host, Nidx) of
Items); #pubsub_item{itemid = {ItemId, Nidx}} -> unset_cached_item(Host, Nidx);
_ -> _ -> ok
true
end; end;
{result, _} ->
ok;
Error -> Error ->
Error Error
end; end;
(_) -> (_) ->
true true
end, end, Items);
lists:usort(lists:flatten(Affs))); Error ->
{Error, _} -> Error
?DEBUG("on_user_offline ~p", [Error])
end. end.