diff options
-rw-r--r-- | src/rexi.erl | 10 | ||||
-rw-r--r-- | src/rexi_server.erl | 9 |
2 files changed, 16 insertions, 3 deletions
diff --git a/src/rexi.erl b/src/rexi.erl index 745afedb..2608ee24 100644 --- a/src/rexi.erl +++ b/src/rexi.erl @@ -1,6 +1,6 @@ -module(rexi). -export([start/0, stop/0, restart/0]). --export([cast/2, cast/3]). +-export([cast/2, cast/3, kill/2]). -export([reply/1]). -define(SERVER, rexi_server). @@ -21,7 +21,7 @@ cast(Node, MFA) -> %% @doc Executes apply(M, F, A) on Node. %% You might want to use this instead of rpc:cast/4 for two reasons. First, %% the Caller pid and the returned reference are inserted into the remote -%% process' dictionary as 'rexi_from', so it has a way to communicate with you. +%% process' dictionary as `rexi_from', so it has a way to communicate with you. %% Second, the remote process is monitored. If it dies, Caller will receive a %% message of the form `{rexi_EXIT, Ref, Reason}' where Ref is the returned %% reference and Reason is the exit reason. @@ -31,6 +31,12 @@ cast(Node, Caller, MFA) -> ok = gen_server:cast({?SERVER, Node}, {doit, {Caller,Ref}, MFA}), {ok, Ref}. +%% @doc Sends an async kill signal to the remote process associated with Ref. +%% No rexi_EXIT message will be sent. +-spec kill(node(), reference()) -> ok. +kill(Node, Ref) -> + ok = gen_server:cast({?SERVER, Node}, {kill, Ref}). + %% @doc convenience function to reply to the original rexi Caller. -spec reply(any()) -> any(). reply(Reply) -> diff --git a/src/rexi_server.erl b/src/rexi_server.erl index e06fd86d..6f8b8641 100644 --- a/src/rexi_server.erl +++ b/src/rexi_server.erl @@ -22,7 +22,14 @@ handle_call(_Request, _From, St) -> handle_cast({doit, From, MFA}, #st{workers=Workers} = St) -> {LocalPid, Ref} = spawn_monitor(?MODULE, init_p, [From, MFA]), - {noreply, St#st{workers = add_worker({LocalPid, Ref, From}, Workers)}}. + {noreply, St#st{workers = add_worker({LocalPid, Ref, From}, Workers)}}; + +handle_cast({kill, Ref}, #st{workers=Workers} = St) -> + case find_worker(Ref, Workers) of + {Pid, Ref, _} -> + exit(Pid, kill); + false -> ok end, + {noreply, St#st{workers = remove_worker(Ref, Workers)}}. handle_info({'DOWN', Ref, process, _, normal}, #st{workers=Workers} = St) -> {noreply, St#st{workers = remove_worker(Ref, Workers)}}; |