diff options
Diffstat (limited to 'src/mod_pubsub/pubsub_debug.erl')
-rw-r--r-- | src/mod_pubsub/pubsub_debug.erl | 283 |
1 files changed, 213 insertions, 70 deletions
diff --git a/src/mod_pubsub/pubsub_debug.erl b/src/mod_pubsub/pubsub_debug.erl index 791031e5e..3d4740433 100644 --- a/src/mod_pubsub/pubsub_debug.erl +++ b/src/mod_pubsub/pubsub_debug.erl @@ -1,113 +1,256 @@ -module(pubsub_debug). + -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -compile(export_all). +-spec(nodeid/2 :: +( + Host :: mod_pubsub:host(), + Node :: mod_pubsub:nodeId()) + -> mod_pubsub:nodeIdx() | 0 +). nodeid(Host, Node) -> case mnesia:dirty_read({pubsub_node, {Host, Node}}) of - [N] -> nodeid(N); - _ -> 0 + [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, _='_'}). -nodes() -> [element(2, element(2, N)) || N <- mnesia:dirty_match_object(#pubsub_node{_='_'})]. + +-spec(nodeids/0 :: () -> [0 | mod_pubsub:nodeIdx()]). + +nodeids() -> + [nodeid(Host, Node) + || {Host, Node} <- mnesia:dirty_all_keys(pubsub_node)]. + +-spec(nodeids_by_type/1 :: +( + Type :: binary()) + -> [0 | mod_pubsub:nodeIdx()] +). +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, + _ = '_'}). + +nodes() -> + [element(2, element(2, N)) + || N + <- mnesia:dirty_match_object(#pubsub_node{_ = '_'})]. state(JID, NodeId) -> case mnesia:dirty_read({pubsub_state, {JID, NodeId}}) of - [S] -> S; - _ -> undefined + [S] -> S; + _ -> undefined end. -states(NodeId) -> mnesia:dirty_index_read(pubsub_state, NodeId, #pubsub_state.nodeidx). + +states(NodeId) -> + mnesia:dirty_index_read(pubsub_state, NodeId, + #pubsub_state.nodeidx). + 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, '_'}, _='_'}). + +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 + case mnesia:dirty_read({pubsub_item, {ItemId, NodeId}}) + of + [I] -> I; + _ -> undefined end. -items(NodeId) -> mnesia:dirty_index_read(pubsub_item, NodeId, #pubsub_item.nodeidx). + +items(NodeId) -> + mnesia:dirty_index_read(pubsub_item, NodeId, + #pubsub_item.nodeidx). + 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 <- states(NodeId), S#pubsub_state.affiliation==owner]. +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 =/= []]. + +owners(NodeId) -> + [stateid(S) + || S <- states(NodeId), + S#pubsub_state.affiliation == owner]. orphan_items(NodeId) -> - itemids(NodeId) -- lists:foldl(fun(S, A) -> A++S#pubsub_state.items end, [], states(NodeId)). + itemids(NodeId) -- + lists:foldl(fun (S, A) -> A ++ S#pubsub_state.items end, + [], states(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]. + [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]. + [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))). -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] = 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}), + [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). + 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). + 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; - _ -> - [] + 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. |