Permalink
Browse files

taking care of failure modes in the mediator.

  • Loading branch information...
1 parent 44ab56e commit 36c071242bf967e5c473bce133b1318f8930685e Cliff Moon committed Jul 8, 2008
Showing with 38 additions and 18 deletions.
  1. +16 −9 elibs/mediator.erl
  2. +0 −1 elibs/membership.erl
  3. +2 −2 elibs/storage_server.erl
  4. +20 −6 etest/mediator_test.erl
View
@@ -85,13 +85,13 @@ init({R, W, N}) ->
%% @end
%%--------------------------------------------------------------------
handle_call({get, Key}, _From, State) ->
- {reply, {ok, internal_get(Key, State)}, State};
+ {reply, internal_get(Key, State), State};
handle_call({put, Key, Context, Value}, _From, State) ->
{reply, internal_put(Key, Context, Value, State), State};
handle_call({has_key, Key}, _From, State) ->
- {reply, {ok, internal_has_key(Key, State)}, State};
+ {reply, internal_has_key(Key, State), State};
handle_call({delete, Key}, _From, State) ->
{reply, internal_delete(Key, State), State};
@@ -144,24 +144,29 @@ code_change(_OldVsn, State, _Extra) ->
internal_put(Key, Context, Value, #mediator{n=N,w=W}) ->
Servers = membership:server_for_key(Key, N),
+ error_logger:info_msg("put servers: ~p~n", [Servers]),
Incremented = vector_clock:increment(node(), Context),
MapFun = fun(Server) ->
storage_server:put(Server, Key, Incremented, Value)
end,
- {Good, _Bad} = pcall(MapFun, Servers),
+ {Good, Bad} = pcall(MapFun, Servers),
+ error_logger:info_msg("good, bad: ~p~n", [{Good, Bad}]),
+ Blah = blah,
if
length(Good) >= W -> {ok, length(Good)};
true -> {failure, error_message(Good, N, W)}
end.
internal_get(Key, #mediator{n=N,r=R}) ->
Servers = membership:server_for_key(Key, N),
+ error_logger:info_msg("put servers: ~p~n", [Servers]),
MapFun = fun(Server) ->
storage_server:get(Server, Key)
end,
- {Good, _Bad} = pcall(MapFun, Servers),
- if
- length(Good) >= R -> resolve_read(Good);
+ {Good, Bad} = pcall(MapFun, Servers),
+ error_logger:info_msg("good, bad: ~p~n", [{Good, Bad}]),
+ if
+ length(Good) >= R -> {ok, resolve_read(Good)};
true -> {failure, error_message(Good, N, R)}
end.
@@ -172,13 +177,12 @@ internal_has_key(Key, #mediator{n=N,r=R}) ->
end,
{Good, _Bad} = pcall(MapFun, Servers),
if
- length(Good) >= R -> resolve_has_key(Good);
+ length(Good) >= R -> {ok, resolve_has_key(Good)};
true -> {failure, error_message(Good, N, R)}
end.
internal_delete(Key, #mediator{n=N,w=W}) ->
Servers = membership:server_for_key(key, N),
- error_logger:info_msg("servers: ~p", [Servers]),
MapFun = fun(Server) ->
storage_server:delete(Server, Key, 10000)
end,
@@ -191,7 +195,10 @@ internal_delete(Key, #mediator{n=N,w=W}) ->
end.
resolve_read([First|Responses]) ->
- lists:foldr({vector_clock, resolve}, First, Responses).
+ case First of
+ not_found -> not_found;
+ _ -> lists:foldr({vector_clock, resolve}, First, Responses)
+ end.
resolve_has_key(Good) ->
{True, False} = lists:partition(fun(E) -> E end, Good),
@@ -240,7 +240,6 @@ nearest_server(Code, N, State, AlreadyFound) ->
FoundCode -> FoundCode
end,
ServerName = dict:fetch(ServerCode, Table),
- error_logger:info_msg("ServerName ~p", [ServerName]),
{removed, ModState} = int_remove_node(ServerName, State),
[dict:fetch(ServerCode, Table) | nearest_server(ServerCode, N-1, ModState)].
@@ -109,13 +109,13 @@ handle_call({has_key, Key}, _From, State = #storage{module=Module,table=Table})
handle_call({delete, Key}, _From, State = #storage{module=Module,table=Table}) ->
case catch Module:delete(Key, Table) of
{ok, ModifiedTable} ->
- error_logger:info_msg("~p", [State#storage{table=ModifiedTable}]),
+ error_logger:info_msg("delete state: ~p~n", [State#storage{table=ModifiedTable}]),
{reply, ok, State#storage{table=ModifiedTable}};
Failure -> {reply, {failure, Failure}, State}
end;
handle_call(info, _From, State = #storage{module=Module, table=Table}) ->
- {reply, Module:info(Table), State};
+ {reply, State, State};
handle_call(close, _From, State) ->
{stop, shutdown, ok, State}.
@@ -28,10 +28,24 @@ all_servers_working_test() ->
{ok, {_Context, <<"value1">>}} = mediator:get(<<"key1">>),
{ok, true} = mediator:has_key(<<"key1">>),
{ok, 3} = mediator:delete(<<"key1">>),
- error_logger:info_msg("~p~p~p~n", [gen_server:call({good_store1, node()}, info), gen_server:call({good_store2, node()}, info), gen_server:call({good_store3, node()}, info)]),
- error_logger:info_msg("~p~p~p~n", [gen_server:call({good_store1, node()}, info), gen_server:call({good_store2, node()}, info), gen_server:call({good_store3, node()}, info)]),
- error_logger:info_msg("~p~p~p~n", [gen_server:call({good_store1, node()}, info), gen_server:call({good_store2, node()}, info), gen_server:call({good_store3, node()}, info)]),
- error_logger:info_msg("~p~p~p~n", [gen_server:call({good_store1, node()}, info), gen_server:call({good_store2, node()}, info), gen_server:call({good_store3, node()}, info)]),
{ok, false} = mediator:has_key(<<"key1">>),
- % {ok, not_found} = mediator:get(<<"key1">>),
- stop_integrated(3, 0).
+ {ok, not_found} = mediator:get(<<"key1">>),
+ stop_integrated(3, 0).
+
+one_bad_server_test() ->
+ init_integrated(2, 1, {2, 2, 3}),
+ {ok, 2} = mediator:put(<<"key1">>, [], <<"value1">>),
+ {ok, {_Context, <<"value1">>}} = mediator:get(<<"key1">>),
+ {ok, true} = mediator:has_key(<<"key1">>),
+ {ok, 2} = mediator:delete(<<"key1">>),
+ {ok, false} = mediator:has_key(<<"key1">>),
+ {ok, not_found} = mediator:get(<<"key1">>),
+ stop_integrated(2, 1).
+
+two_bad_servers_test() ->
+ init_integrated(1, 2, {2, 2, 3}),
+ {failure, _} = mediator:put(<<"key1">>, [], <<"value1">>),
+ {failure, _} = mediator:get(<<"key1">>),
+ {failure, _} = mediator:delete(<<"key1">>),
+ {failure, _} = mediator:has_key(<<"key1">>),
+ stop_integrated(1, 2).

0 comments on commit 36c0712

Please sign in to comment.