|
| 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