summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Kocoloski <adam@cloudant.com>2010-05-10 16:06:34 -0400
committerBrad Anderson <brad@cloudant.com>2010-05-10 16:36:47 -0400
commitcadb7ffad91c9a79f454fc215fa135ceef0910c5 (patch)
tree886e0f52e19cece5ec0776b20348726ec7e1ee5d
parent513cdd3ac1e23c8bf1f71c6225348f162f193d2d (diff)
add function to make a non-blocking gen_server:call (cherry picked from commit 52ab0e4418e0e3cfeb848367f05813d312a6085e)
-rw-r--r--src/rexi.erl27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/rexi.erl b/src/rexi.erl
index 2608ee24..fd195a26 100644
--- a/src/rexi.erl
+++ b/src/rexi.erl
@@ -37,8 +37,35 @@ cast(Node, Caller, MFA) ->
kill(Node, Ref) ->
ok = gen_server:cast({?SERVER, Node}, {kill, Ref}).
+%% @equiv async_server_call(Server, self(), Request)
+-spec async_server_call(pid() | {atom(),node()}, any()) -> reference().
+async_server_call(Server, Request) ->
+ async_server_call(Server, self(), Request).
+
+%% @doc Sends a properly formatted gen_server:call Request to the Server and
+%% returns the reference which the Server will include in its reply. The
+%% function acts more like cast() than call() in that the server process
+%% is not monitored. Clients who want to know if the server is alive should
+%% monitor it themselves before calling this function.
+-spec async_server_call(pid() | {atom(),node()}, pid(), any()) -> reference().
+async_server_call(Server, Caller, Name, Request) ->
+ Ref = make_ref(),
+ do_send(Server, {'$gen_call', {Caller,Ref}, Request}),
+ Ref.
+
%% @doc convenience function to reply to the original rexi Caller.
-spec reply(any()) -> any().
reply(Reply) ->
{Caller, Ref} = get(rexi_from),
erlang:send(Caller, {Ref,Reply}).
+
+%% internal functions %%
+
+% send a message as quickly as possible
+do_send(Dest, Msg) ->
+ case erlang:send(Dest, Msg, [noconnect]) of
+ noconnect ->
+ spawn(erlang, send, [Dest, Msg]);
+ ok ->
+ ok
+ end.