keep a circular buffer of errors cached in memory
diff --git a/src/rexi.erl b/src/rexi.erl
index 0ba77bd..9d34c51 100644
--- a/src/rexi.erl
+++ b/src/rexi.erl
@@ -44,7 +44,7 @@
 -spec cast(node(), pid(), {atom(), atom(), list()}) -> reference().
 cast(Node, Caller, MFA) ->
     Ref = make_ref(),
-    ok = gen_server:cast({?SERVER, Node}, {doit, {Caller,Ref}, MFA}),
+    ok = gen_server:cast({?SERVER, Node}, {doit, {Caller,Ref}, get(nonce), MFA}),
     Ref.
 
 %% @doc Sends an async kill signal to the remote process associated with Ref.
diff --git a/src/rexi_server.erl b/src/rexi_server.erl
index b5db9ec..2161099 100644
--- a/src/rexi_server.erl
+++ b/src/rexi_server.erl
@@ -15,14 +15,18 @@
 -module(rexi_server).
 -behaviour(gen_server).
 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
-    code_change/3]).
+    code_change/3, calls/1, set_call_buffer_size/1]).
 
--export([start_link/0, init_p/2]).
+-export([start_link/0, init_p/3]).
 
 -include_lib("eunit/include/eunit.hrl").
 
 -record(st, {
-    workers = ets:new(workers, [private, {keypos,2}])
+    workers = ets:new(workers, [private, {keypos,2}]),
+    err_cache = queue:new(),
+    err_cache_max = 20,
+    err_cache_len = 0
+
 }).
 
 start_link() ->
@@ -31,13 +35,40 @@
 init([]) ->
     {ok, #st{}}.
 
+calls(N) ->
+    {ok, gen_server:call(?MODULE,{calls, N},infinity)}.
+
+set_call_buffer_size(N) ->
+    {ok, gen_server:call(?MODULE,{cache_max, N},infinity)}.
+
+handle_call({calls, N}, _From, #st{err_cache=Q}=St) ->
+    ErrList = lists:sublist(lists:reverse(queue:to_list(Q)),1,N),
+    {reply,ErrList,St};
+
+handle_call({cache_max, N}, _From, #st{err_cache_len=Len,
+                                       err_cache_max=Max, err_cache=Q}=St) ->
+    {NewQ,NewLen} = case N < Len of
+           true ->
+               List = queue:to_list(Q),
+               {queue:from_list(lists:sublist(List,(Len-N)+1,Len)),
+                N};
+           false ->
+               {Q,Len}
+           end,
+    {reply, Max, St#st{err_cache_max=N, err_cache_len=NewLen, err_cache=NewQ}};
 handle_call(_Request, _From, St) ->
     {reply, ignored, St}.
 
+
 handle_cast({doit, From, MFA}, #st{workers=Workers} = St) ->
-    {LocalPid, Ref} = spawn_monitor(?MODULE, init_p, [From, MFA]),
+    {LocalPid, Ref} = spawn_monitor(?MODULE, init_p, [From, MFA, ""]),
     {noreply, St#st{workers = add_worker({LocalPid, Ref, From}, Workers)}};
 
+handle_cast({doit, From, Nonce, MFA}, #st{workers=Workers} = St) ->
+    {LocalPid, Ref} = spawn_monitor(?MODULE, init_p, [From, MFA, Nonce]),
+    {noreply, St#st{workers = add_worker({LocalPid, Ref, From}, Workers)}};
+
+
 handle_cast({kill, FromRef}, #st{workers=Workers} = St) ->
     case find_worker_from(FromRef, Workers) of
     {Pid, KeyRef, {_, FromRef}} ->
@@ -51,11 +82,28 @@
 handle_info({'DOWN', Ref, process, _, normal}, #st{workers=Workers} = St) ->
     {noreply, St#st{workers = remove_worker(Ref, Workers)}};
 
-handle_info({'DOWN', Ref, process, Pid, Reason}, #st{workers=Workers} = St) ->
+handle_info({'DOWN', Ref, process, Pid, Reason}, #st{workers=Workers,
+                                                    err_cache=Q,
+                                                    err_cache_max=Max,
+                                                    err_cache_len=Len} = St) ->
     case find_worker(Ref, Workers) of
     {Pid, Ref, From} ->
-        notify_caller(From, Reason),
-        {noreply, St#st{workers = remove_worker(Ref, Workers)}};
+
+        {Error,{M,F,A},Nonce,Stack} = Reason,
+
+        {NewQ,NewLen} =
+        case Len >= Max of
+        true ->
+            Q1 = queue:drop(Q),
+            {Q1,Len};
+        _ ->
+            {Q,Len+1}
+        end,
+        NewQ1 = queue:in([now(),From,Nonce,M,F,A],NewQ),
+        notify_caller(From, {Error,Stack}),
+        {noreply, St#st{workers = remove_worker(Ref, Workers),
+                       err_cache=NewQ1,
+                       err_cache_len=NewLen}};
     false ->
         {noreply, St}
     end;
@@ -71,14 +119,14 @@
     {ok, St}.
 
 %% @doc initializes a process started by rexi_server.
--spec init_p({pid(), reference()}, {atom(), atom(), list()}) -> any().
-init_p(From, {M,F,A}) ->
+-spec init_p({pid(), reference()}, {atom(), atom(), list()}, string()) -> any().
+init_p(From, {M,F,A}, Nonce) ->
     put(rexi_from, From),
     put(initial_call, {M,F,length(A)}),
     try apply(M, F, A) catch exit:normal -> ok; Class:Reason ->
         Stack = clean_stack(),
-        error_logger:error_report([{?MODULE, {Class, Reason}}, Stack]),
-        exit({Reason, Stack})
+        error_logger:error_report([{?MODULE, Nonce, {Class, Reason}}, Stack]),
+        exit({Reason,{M,F,A},Nonce,Stack})
     end.
 
 %% internal