Skip to content

Commit 3def9e1

Browse files
Merge pull request #7834 from rabbitmq/mergify/bp/v3.12.x/pr-7825
If a queue process is hibernated, consider it up (backport #7825)
2 parents c941cb8 + 9de5a60 commit 3def9e1

File tree

2 files changed

+99
-6
lines changed

2 files changed

+99
-6
lines changed

deps/rabbit/src/rabbit_amqqueue.erl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,14 +1077,17 @@ list_local_names_down() ->
10771077
is_down(Q)].
10781078

10791079
is_down(Q) ->
1080-
try
1081-
info(Q, [state]) == [{state, down}]
1082-
catch
1083-
_:_ ->
1084-
true
1080+
case rabbit_process:is_process_hibernated(amqqueue:get_pid(Q)) of
1081+
true -> false;
1082+
false ->
1083+
try
1084+
info(Q, [state]) == [{state, down}]
1085+
catch
1086+
_:_ ->
1087+
true
1088+
end
10851089
end.
10861090

1087-
10881091
-spec sample_local_queues() -> [amqqueue:amqqueue()].
10891092
sample_local_queues() -> sample_n_by_name(list_local_names(), 300).
10901093

deps/rabbit/src/rabbit_process.erl

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
%% This Source Code Form is subject to the terms of the Mozilla Public
2+
%% License, v. 2.0. If a copy of the MPL was not distributed with this
3+
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
%%
5+
%% Copyright (c) 2007-2023 VMware, Inc. or its affiliates. All rights reserved.
6+
%%
7+
8+
-module(rabbit_process).
9+
10+
-export([on_running_node/1,
11+
is_process_alive/1,
12+
is_process_hibernated/1,
13+
is_registered_process_alive/1]).
14+
15+
-spec on_running_node(Pid) -> OnRunningNode when
16+
Pid :: pid(),
17+
OnRunningNode :: boolean().
18+
%% @doc Indicates if the specified process runs on a member of the cluster.
19+
%%
20+
%% @param Pid the PID of the process to check
21+
%% @returns true if the process runs on one of the cluster members, false
22+
%% otherwise.
23+
24+
on_running_node(Pid) ->
25+
Node = node(Pid),
26+
rabbit_nodes:is_running(Node).
27+
28+
%% This requires the process be in the same running cluster as us
29+
%% (i.e. not partitioned or some random node).
30+
%%
31+
%% See also rabbit_misc:is_process_alive/1 which does not.
32+
33+
-spec is_process_alive(Pid) -> IsAlive when
34+
Pid :: pid() | {RegisteredName, Node},
35+
RegisteredName :: atom(),
36+
Node :: node(),
37+
IsAlive :: boolean().
38+
%% @doc Indicates if the specified process is alive.
39+
%%
40+
%% Unlike {@link erlang:is_process_alive/1}, this function works with remote
41+
%% processes and registered processes. However, the process must run on one of
42+
%% the cluster members.
43+
%%
44+
%% @param Pid the PID or name of the process to check
45+
%% @returns true if the process is alive runs on one of the cluster members,
46+
%% false otherwise.
47+
48+
is_process_alive(Pid) when is_pid(Pid) ->
49+
on_running_node(Pid)
50+
andalso
51+
rpc:call(node(Pid), erlang, is_process_alive, [Pid]) =:= true;
52+
is_process_alive({Name, Node}) when is_atom(Name) andalso is_atom(Node) ->
53+
case rabbit_nodes:is_running(Node) of
54+
true ->
55+
try
56+
erpc:call(Node, ?MODULE, is_registered_process_alive, [Name])
57+
catch
58+
error:{exception, undef, [{?MODULE, _, _, _} | _]} ->
59+
rpc:call(
60+
Node,
61+
rabbit_mnesia, is_registered_process_alive, [Name])
62+
end;
63+
false ->
64+
false
65+
end.
66+
67+
-spec is_registered_process_alive(RegisteredName) -> IsAlive when
68+
RegisteredName :: atom(),
69+
IsAlive :: boolean().
70+
%% @doc Indicates if the specified registered process is alive.
71+
%%
72+
%% The process must be local to this node.
73+
%%
74+
%% @param RegisteredName the name of the registered process
75+
%% @returns true if the process is alive, false otherwise.
76+
77+
is_registered_process_alive(Name) ->
78+
is_pid(whereis(Name)).
79+
80+
-spec is_process_hibernated(Pid) -> IsHibernated when
81+
Pid :: pid(),
82+
IsHibernated :: boolean().
83+
%% @doc Indicates if the specified process is hibernated.
84+
%%
85+
%% @param Pid the PID or name of the process to check
86+
%% @returns true if the process is hibernated on one of the cluster members,
87+
%% false otherwise.
88+
89+
is_process_hibernated(Pid) when is_pid(Pid) ->
90+
{current_function,{erlang,hibernate,3}} == erlang:process_info(Pid, current_function).

0 commit comments

Comments
 (0)