add ability to kill a remote worker, BugzID 10096

diff --git a/src/rexi.erl b/src/rexi.erl
index 745afed..2608ee2 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 @@
 %% @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 @@
     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 e06fd86..6f8b864 100644
--- a/src/rexi_server.erl
+++ b/src/rexi_server.erl
@@ -22,7 +22,14 @@
 
 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)}};