mirror of
https://github.com/processone/ejabberd.git
synced 2024-07-02 23:06:21 +02:00
added pubsub helper modules
This commit is contained in:
parent
652774a83c
commit
2624f3ba51
41
src/mod_pubsub/pubsub_clean.erl
Normal file
41
src/mod_pubsub/pubsub_clean.erl
Normal file
|
@ -0,0 +1,41 @@
|
|||
-module(pubsub_clean).
|
||||
|
||||
-define(TIMEOUT, 1000*600). % 1 minute
|
||||
|
||||
-export([start/0, loop/0, subscribed/1, offline/1]).
|
||||
|
||||
start() ->
|
||||
Pid = spawn(?MODULE, loop, []),
|
||||
register(pubsub_clean, Pid),
|
||||
Pid.
|
||||
|
||||
loop() ->
|
||||
receive
|
||||
purge -> purge()
|
||||
after ?TIMEOUT -> purge()
|
||||
end,
|
||||
loop().
|
||||
|
||||
purge() ->
|
||||
{Sessions, Subscriptions} = {mnesia:table_info(session,size),mnesia:table_info(pubsub_state,size)},
|
||||
if Subscriptions > Sessions + 500 ->
|
||||
lists:foreach(fun(K) ->
|
||||
[N]=mnesia:dirty_read({pubsub_node, K}),
|
||||
I=element(3,N),
|
||||
lists:foreach(fun(JID) ->
|
||||
mnesia:dirty_delete({pubsub_state, {JID, I}})
|
||||
end, offline(subscribed(I)))
|
||||
end, mnesia:dirty_all_keys(pubsub_node));
|
||||
true ->
|
||||
ok
|
||||
end.
|
||||
|
||||
subscribed(NodeId) ->
|
||||
lists:map(fun(S) ->
|
||||
element(1,element(2,S))
|
||||
end, mnesia:dirty_match_object({pubsub_state, {'_',NodeId},'_',none,subscribed})).
|
||||
|
||||
offline(Jids) ->
|
||||
lists:filter(fun({U,S,""}) -> ejabberd_sm:get_user_resources(U,S) == [];
|
||||
({U,S,R}) -> not lists:member(R,ejabberd_sm:get_user_resources(U,S))
|
||||
end, Jids).
|
112
src/mod_pubsub/pubsub_debug.erl
Normal file
112
src/mod_pubsub/pubsub_debug.erl
Normal file
|
@ -0,0 +1,112 @@
|
|||
-module(pubsub_debug).
|
||||
-author('christophe.romain@process-one.net').
|
||||
|
||||
-include("pubsub.hrl").
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
nodeid(Host, Node) ->
|
||||
case mnesia:dirty_read({pubsub_node, {Host, Node}}) of
|
||||
[N] -> nodeid(N);
|
||||
_ -> 0
|
||||
end.
|
||||
nodeid(N) -> N#pubsub_node.id.
|
||||
nodeids() -> [nodeid(Host, Node) || {Host, Node} <- mnesia:dirty_all_keys(pubsub_node)].
|
||||
nodeids_by_type(Type) -> [nodeid(N) || N <- mnesia:dirty_match_object(#pubsub_node{type=Type, _='_'})].
|
||||
nodeids_by_option(Key, Value) -> [nodeid(N) || N <- mnesia:dirty_match_object(#pubsub_node{_='_'}), lists:member({Key, Value}, N#pubsub_node.options)].
|
||||
nodeids_by_owner(JID) -> [nodeid(N) || N <- mnesia:dirty_match_object(#pubsub_node{_='_'}), lists:member(JID, N#pubsub_node.owners)].
|
||||
nodes_by_id(I) -> mnesia:dirty_match_object(#pubsub_node{id=I, _='_'}).
|
||||
|
||||
state(JID, NodeId) ->
|
||||
case mnesia:dirty_read({pubsub_state, {JID, NodeId}}) of
|
||||
[S] -> S;
|
||||
_ -> undefined
|
||||
end.
|
||||
states(NodeId) -> mnesia:dirty_match_object(#pubsub_state{stateid={'_', NodeId}, _='_'}).
|
||||
stateid(S) -> element(1, S#pubsub_state.stateid).
|
||||
stateids(NodeId) -> [stateid(S) || S <- states(NodeId)].
|
||||
states_by_jid(JID) -> mnesia:dirty_match_object(#pubsub_state{stateid={JID, '_'}, _='_'}).
|
||||
|
||||
item(ItemId, NodeId) ->
|
||||
case mnesia:dirty_read({pubsub_item, {ItemId, NodeId}}) of
|
||||
[I] -> I;
|
||||
_ -> undefined
|
||||
end.
|
||||
items(NodeId) -> mnesia:dirty_match_object(#pubsub_item{itemid={'_', NodeId}, _='_'}).
|
||||
itemid(I) -> element(1, I#pubsub_item.itemid).
|
||||
itemids(NodeId) -> [itemid(I) || I <- items(NodeId)].
|
||||
items_by_id(ItemId) -> mnesia:dirty_match_object(#pubsub_item{itemid={ItemId, '_'}, _='_'}).
|
||||
|
||||
affiliated(NodeId) -> [stateid(S) || S <- states(NodeId), S#pubsub_state.affiliation=/=none].
|
||||
subscribed(NodeId) -> [stateid(S) || S <- states(NodeId), S#pubsub_state.subscriptions=/=[]].
|
||||
%subscribed(NodeId) -> [stateid(S) || S <- states(NodeId), S#pubsub_state.subscription=/=none]. %% old record
|
||||
owners(NodeId) -> [stateid(S) || S <- mnesia:dirty_match_object(#pubsub_state{stateid={'_', NodeId}, affiliation=owner, _='_'})].
|
||||
|
||||
orphan_items(NodeId) ->
|
||||
itemids(NodeId) -- lists:foldl(fun(S, A) -> A++S#pubsub_state.items end, [], mnesia:dirty_match_object(#pubsub_state{stateid={'_', NodeId}, _='_'})).
|
||||
newer_items(NodeId, Seconds) ->
|
||||
Now = calendar:universal_time(),
|
||||
Oldest = calendar:seconds_to_daystime(Seconds),
|
||||
[itemid(I) || I <- items(NodeId), calendar:time_difference(calendar:now_to_universal_time(element(1, I#pubsub_item.modification)), Now) < Oldest].
|
||||
older_items(NodeId, Seconds) ->
|
||||
Now = calendar:universal_time(),
|
||||
Oldest = calendar:seconds_to_daystime(Seconds),
|
||||
[itemid(I) || I <- items(NodeId), calendar:time_difference(calendar:now_to_universal_time(element(1, I#pubsub_item.modification)), Now) > Oldest].
|
||||
|
||||
orphan_nodes() -> [I || I <- nodeids(), owners(I)==[]].
|
||||
duplicated_nodes() -> L = nodeids(), lists:usort(L -- lists:seq(1, lists:max(L))).
|
||||
node_options(NodeId) ->
|
||||
[N] = mnesia:dirty_match_object(#pubsub_node{id=NodeId, _='_'}),
|
||||
N#pubsub_node.options.
|
||||
update_node_options(Key, Value, NodeId) ->
|
||||
[N] = mnesia:dirty_match_object(#pubsub_node{id=NodeId, _='_'}),
|
||||
NewOptions = lists:keyreplace(Key, 1, N#pubsub_node.options, {Key, Value}),
|
||||
mnesia:dirty_write(N#pubsub_node{options = NewOptions}).
|
||||
|
||||
check() ->
|
||||
mnesia:transaction(fun() ->
|
||||
case mnesia:read({pubsub_index, node}) of
|
||||
[Idx] ->
|
||||
Free = Idx#pubsub_index.free,
|
||||
Last = Idx#pubsub_index.last,
|
||||
Allocated = lists:seq(1, Last) -- Free,
|
||||
NodeIds = mnesia:foldl(fun(N,A) -> [nodeid(N)|A] end, [], pubsub_node),
|
||||
StateIds = lists:usort(mnesia:foldl(fun(S,A) -> [element(2, S#pubsub_state.stateid)|A] end, [], pubsub_state)),
|
||||
ItemIds = lists:usort(mnesia:foldl(fun(I,A) -> [element(2, I#pubsub_item.itemid)|A] end, [], pubsub_item)),
|
||||
BadNodeIds = NodeIds -- Allocated,
|
||||
BadStateIds = StateIds -- NodeIds,
|
||||
BadItemIds = ItemIds -- NodeIds,
|
||||
Lost = Allocated -- NodeIds,
|
||||
[{bad_nodes, [N#pubsub_node.nodeid || N <- lists:flatten([mnesia:match_object(#pubsub_node{id=I, _='_'}) || I <- BadNodeIds])]},
|
||||
{bad_states, lists:foldl(fun(N,A) -> A++[{I,N} || I <- stateids(N)] end, [], BadStateIds)},
|
||||
{bad_items, lists:foldl(fun(N,A) -> A++[{I,N} || I <- itemids(N)] end, [], BadItemIds)},
|
||||
{lost_idx, Lost},
|
||||
{orphaned, [I || I <- NodeIds, owners(I)==[]]},
|
||||
{duplicated, lists:usort(NodeIds -- lists:seq(1, lists:max(NodeIds)))}];
|
||||
_ ->
|
||||
no_index
|
||||
end
|
||||
end).
|
||||
|
||||
rebuild_index() ->
|
||||
mnesia:transaction(fun() ->
|
||||
NodeIds = mnesia:foldl(fun(N,A) -> [nodeid(N)|A] end, [], pubsub_node),
|
||||
Last = lists:max(NodeIds),
|
||||
Free = lists:seq(1, Last) -- NodeIds,
|
||||
mnesia:write(#pubsub_index{index = node, last = Last, free = Free})
|
||||
end).
|
||||
|
||||
pep_subscriptions(LUser, LServer, LResource) ->
|
||||
case ejabberd_sm:get_session_pid({LUser, LServer, LResource}) of
|
||||
C2SPid when is_pid(C2SPid) ->
|
||||
case catch ejabberd_c2s:get_subscribed(C2SPid) of
|
||||
Contacts when is_list(Contacts) ->
|
||||
lists:map(fun({U, S, _}) ->
|
||||
io_lib:format("~s@~s", [U, S])
|
||||
end, Contacts);
|
||||
_ ->
|
||||
[]
|
||||
end;
|
||||
_ ->
|
||||
[]
|
||||
end.
|
Loading…
Reference in New Issue
Block a user