25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-26 17:38:45 +01: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 ->
{result, Affs} = node_action(Host, Type, Items = lists:member(<<"retract-items">>, Features)
get_entity_affiliations, andalso lists:member(<<"persistent-items">>, Features),
[Host, LJID]), if Items ->
{Status, [Affs | Acc]} {result, Affs} = node_action(Host, Type,
get_entity_affiliations, [Host, LJID]),
{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 ({Node, Affiliation}) ->
Options = Node#pubsub_node.options,
Publisher = lists:member(Affiliation, [owner,publisher,publish_only]),
Open = (get_option(Options, publish_model) == open),
Purge = (get_option(Options, purge_offline)
andalso get_option(Options, persist_items)),
if (Publisher or Open) and Purge ->
purge_offline(Host, LJID, Node);
true ->
ok
end
end, lists:usort(lists:flatten(Affs)));
{Error, _} ->
?DEBUG("on_user_offline ~p", [Error])
end.
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),
{_, NodeId} = Node#pubsub_node.nodeid,
lists:foreach(fun lists:foreach(fun
({#pubsub_node{nodeid = {_, Node}, options = Options, type = Type}, Aff}) (#pubsub_item{itemid = {ItemId, _}, modification = {_, {U, S, _}}})
when Aff == owner orelse Aff == publisher -> when (U == User) and (S == Server) ->
Action = fun (#pubsub_node{type = NType, id = Nidx}) -> case node_action(Host, Type, delete_item, [Nidx, {U, S, <<>>}, PublishModel, ItemId]) of
node_call(Host, NType, get_items, [Nidx, service_jid(Host), none]) {result, {_, broadcast}} ->
end, broadcast_retract_items(Host, NodeId, Nidx, Type, Options, [ItemId], ForceNotify),
case transaction(Host, Node, Action, sync_dirty) of case get_cached_item(Host, Nidx) of
{result, {_, {[], _}}} -> #pubsub_item{itemid = {ItemId, Nidx}} -> unset_cached_item(Host, Nidx);
true; _ -> ok
{result, {_, {Items, _}}} ->
Features = plugin_features(Host, Type),
case {lists:member(<<"retract-items">>, Features),
lists:member(<<"persistent-items">>, Features),
get_option(Options, persist_items),
get_option(Options, purge_offline)}
of
{true, true, true, true} ->
ForceNotify = get_option(Options, notify_retract),
lists:foreach(fun
(#pubsub_item{itemid = {ItemId, _},
modification = {_, {U, S, _}}})
when (U == User) and (S == Server) ->
delete_item(Host, Node, LJID, ItemId, ForceNotify);
(_) ->
true
end,
Items);
_ ->
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.