-
Notifications
You must be signed in to change notification settings - Fork 231
Changes needed to expose FSM timeouts to clients #521
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -250,7 +250,13 @@ delete(Bucket,Key,Options,Timeout) when is_list(Options) -> | |
| ReqId = mk_reqid(), | ||
| riak_kv_delete_sup:start_delete(Node, [ReqId, Bucket, Key, Options, Timeout, | ||
| Me, ClientId]), | ||
| wait_for_reqid(ReqId, Timeout); | ||
| RTimeout = recv_timeout(Options), | ||
| lager:info("timeouts r ~p t ~p > ~p", | ||
| [RTimeout, Timeout, RTimeout > Timeout]), | ||
| case RTimeout > Timeout of | ||
| true -> wait_for_reqid(ReqId, Timeout); | ||
| false -> wait_for_reqid(ReqId, RTimeout) | ||
| end; | ||
| delete(Bucket,Key,RW,Timeout) -> | ||
| delete(Bucket,Key,[{rw, RW}], Timeout). | ||
|
|
||
|
|
@@ -295,7 +301,11 @@ delete_vclock(Bucket,Key,VClock,Options,Timeout) when is_list(Options) -> | |
| ReqId = mk_reqid(), | ||
| riak_kv_delete_sup:start_delete(Node, [ReqId, Bucket, Key, Options, Timeout, | ||
| Me, ClientId, VClock]), | ||
| wait_for_reqid(ReqId, Timeout); | ||
| RTimeout = recv_timeout(Options), | ||
| case RTimeout > Timeout of | ||
|
||
| true -> wait_for_reqid(ReqId, Timeout); | ||
| false -> wait_for_reqid(ReqId, RTimeout) | ||
| end; | ||
| delete_vclock(Bucket,Key,VClock,RW,Timeout) -> | ||
| delete_vclock(Bucket,Key,VClock,[{rw, RW}],Timeout). | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -168,20 +168,6 @@ init(Props) -> | |
| %% bindings from the dispatch, as well as any vtag | ||
| %% query parameter. | ||
| service_available(RD, Ctx=#ctx{riak=RiakProps}) -> | ||
| Timeout = case wrq:get_req_header(?HEAD_TIMEOUT, RD) of | ||
| undefined -> ?DEFAULT_TIMEOUT; | ||
| TimeoutStr -> | ||
| try | ||
| list_to_integer(TimeoutStr) | ||
| catch | ||
| _:_ -> | ||
| lager:error("Bad timeout value ~p, " | ||
| "using ~d~n", | ||
| [TimeoutStr, ?DEFAULT_TIMEOUT]), | ||
| ?DEFAULT_TIMEOUT | ||
| end | ||
| end, | ||
|
|
||
| case riak_kv_wm_utils:get_riak_client(RiakProps, riak_kv_wm_utils:get_client_id(RD)) of | ||
| {ok, C} -> | ||
| {true, | ||
|
|
@@ -197,8 +183,7 @@ service_available(RD, Ctx=#ctx{riak=RiakProps}) -> | |
| undefined -> undefined; | ||
| K -> list_to_binary(riak_kv_wm_utils:maybe_decode_uri(RD, K)) | ||
| end, | ||
| vtag=wrq:get_qs_value(?Q_VTAG, RD), | ||
| timeout=Timeout | ||
| vtag=wrq:get_qs_value(?Q_VTAG, RD) | ||
| }}; | ||
| Error -> | ||
| {false, | ||
|
|
@@ -245,29 +230,66 @@ malformed_request(RD, Ctx) when Ctx#ctx.method =:= 'POST' | |
| undefined -> | ||
| {true, missing_content_type(RD), Ctx}; | ||
| _ -> | ||
| case malformed_rw_params(RD, Ctx) of | ||
| Result={true, _, _} -> | ||
| case malformed_timeout_param(RD, Ctx) of | ||
| Result={true, _, _} -> | ||
| Result; | ||
| {false, RWRD, RWCtx} -> | ||
| case malformed_link_headers(RWRD, RWCtx) of | ||
| Result = {true, _, _} -> | ||
| {false, ToRD, ToCtx} -> | ||
| case malformed_rw_params(ToRD, ToCtx) of | ||
| Result={true, _, _} -> | ||
| Result; | ||
| {false, RWLH, LHCtx} -> | ||
| malformed_index_headers(RWLH, LHCtx) | ||
| {false, RWRD, RWCtx} -> | ||
| case malformed_link_headers(RWRD, RWCtx) of | ||
| Result = {true, _, _} -> | ||
| Result; | ||
| {false, RWLH, LHCtx} -> | ||
| malformed_index_headers(RWLH, LHCtx) | ||
| end | ||
| end | ||
| end | ||
| end; | ||
| malformed_request(RD, Ctx) -> | ||
| case malformed_rw_params(RD, Ctx) of | ||
| Result = {true, _, _} -> | ||
| malformed_request(RD, Ctx) -> | ||
| case malformed_timeout_param(RD, Ctx) of | ||
| Result={true, _, _} -> | ||
| Result; | ||
| {false, ResRD, ResCtx} -> | ||
| DocCtx = ensure_doc(ResCtx), | ||
| case DocCtx#ctx.doc of | ||
| {error, Reason} -> | ||
| handle_common_error(Reason, ResRD, DocCtx); | ||
| _ -> | ||
| {false, ResRD, DocCtx} | ||
| {false, ToRD, ToCtx} -> | ||
| case malformed_rw_params(ToRD, ToCtx) of | ||
| Result = {true, _, _} -> | ||
| Result; | ||
| {false, ResRD, ResCtx} -> | ||
| DocCtx = ensure_doc(ResCtx), | ||
| case DocCtx#ctx.doc of | ||
| {error, Reason} -> | ||
| handle_common_error(Reason, ResRD, DocCtx); | ||
| _ -> | ||
| {false, ResRD, DocCtx} | ||
| end | ||
| end | ||
| end. | ||
|
|
||
| %% @spec malformed_timeout_param(reqdata(), context()) -> | ||
| %% {boolean(), reqdata(), context()} | ||
| %% @doc Check that the timeout parameter is are a | ||
| %% string-encoded integer. Store the integer value | ||
| %% in context() if so. | ||
| malformed_timeout_param(RD, Ctx) -> | ||
| case wrq:get_qs_value("timeout", none, RD) of | ||
| none -> | ||
| {false, RD, Ctx}; | ||
| TimeoutStr -> | ||
| try | ||
| Timeout = list_to_integer(TimeoutStr), | ||
| {false, RD, Ctx#ctx{timeout=Timeout}} | ||
| catch | ||
| _:_ -> | ||
| {true, | ||
| wrq:append_to_resp_body(io_lib:format("Bad timeout " | ||
| "value ~p, " | ||
| "using ~p~n", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you provide a bad timeout value, it doesn't actually use the default but returns a 400 response. |
||
| [TimeoutStr, | ||
| ?DEFAULT_TIMEOUT]), | ||
| wrq:set_resp_header(?HEAD_CTYPE, | ||
| "text/plain", RD)), | ||
| Ctx} | ||
| end | ||
| end. | ||
|
|
||
|
|
@@ -611,10 +633,13 @@ accept_doc_body(RD, Ctx=#ctx{bucket=B, key=K, client=C, links=L, index_fields=IF | |
| IndexMD = dict:store(?MD_INDEX, IF, UserMetaMD), | ||
| MDDoc = riak_object:update_metadata(VclockDoc, IndexMD), | ||
| Doc = riak_object:update_value(MDDoc, riak_kv_wm_utils:accept_value(CType, wrq:req_body(RD))), | ||
| Options = case wrq:get_qs_value(?Q_RETURNBODY, RD) of ?Q_TRUE -> [returnbody]; _ -> [] end, | ||
| case C:put(Doc, [{w, Ctx#ctx.w}, {dw, Ctx#ctx.dw}, {pw, Ctx#ctx.pw}, | ||
| {timeout, Ctx#ctx.timeout} | | ||
| Options]) of | ||
| Options0 = case wrq:get_qs_value(?Q_RETURNBODY, RD) of ?Q_TRUE -> [returnbody]; _ -> [] end, | ||
| Options = case Ctx#ctx.timeout of | ||
| undefined -> Options0; | ||
| Else -> [{timeout, Else} | Options0] | ||
| end, | ||
| case C:put(Doc, [{w, Ctx#ctx.w}, {dw, Ctx#ctx.dw}, {pw, Ctx#ctx.pw} | | ||
| Options]) of | ||
| {error, Reason} -> | ||
| handle_common_error(Reason, RD, Ctx); | ||
| ok -> | ||
|
|
@@ -848,19 +873,27 @@ ensure_doc(Ctx=#ctx{doc=undefined, key=undefined}) -> | |
| Ctx#ctx{doc={error, notfound}}; | ||
| ensure_doc(Ctx=#ctx{doc=undefined, bucket=B, key=K, client=C, r=R, | ||
| pr=PR, basic_quorum=Quorum, notfound_ok=NotFoundOK}) -> | ||
| Ctx#ctx{doc=C:get(B, K, [deletedvclock, {r, R}, {pr, PR}, | ||
| {basic_quorum, Quorum}, | ||
| {notfound_ok, NotFoundOK}, | ||
| {timeout, Ctx#ctx.timeout}])}; | ||
| Opts0 = [deletedvclock, {r, R}, {pr, PR}, | ||
| {basic_quorum, Quorum}, | ||
| {notfound_ok, NotFoundOK}], | ||
| Opts = case Ctx#ctx.timeout of | ||
| undefined -> Opts0; | ||
| Else -> Opts0 ++ [{timeout, Else}] | ||
| end, | ||
| Ctx#ctx{doc=C:get(B, K, Opts)}; | ||
| ensure_doc(Ctx) -> Ctx. | ||
|
|
||
| %% @spec delete_resource(reqdata(), context()) -> {true, reqdata(), context()} | ||
| %% @doc Delete the document specified. | ||
| delete_resource(RD, Ctx=#ctx{bucket=B, key=K, client=C, rw=RW, r=R, w=W, | ||
| pr=PR, pw=PW, dw=DW, timeout=Timeout}) -> | ||
| Options = lists:filter(fun({_, default}) -> false; (_) -> true end, | ||
| [{rw, RW}, {r, R}, {w, W}, {pr, PR}, {pw, PW}, {dw, DW}, | ||
| {timeout, Timeout}]), | ||
| pr=PR, pw=PW, dw=DW}) -> | ||
| Options0 = lists:filter(fun({_, default}) -> false; (_) -> true end, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggested refactoring: Opts0 = [{rw, RW}, {r, R}, {w, W}, {pr, PR}, {pw, PW}, {dw, DW}, {timeout, Timeout}],
Options = [ {Opt, Val} || {Opt, Val} <- Opts0, Val /= undefined, Val /= default ]That pattern might also be useful in these other places where you conditionally include the timeout option, e.g. Opts0 ++ [ {timeout, Timeout} || Timeout /= undefined ]
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's done in three different ways in three different places. Would be happy to refactor it to be uniform, but wasn't sure that this PR was the right place.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm ok with adding refactoring all three, or simply making a function to call for the same effect. Cleaning up debt is always good. Sean Cribbs On Apr 1, 2013, at 4:29 PM, Evan Vigil-McClanahan notifications@github.com wrote:
|
||
| [{rw, RW}, {r, R}, {w, W}, {pr, PR}, | ||
| {pw, PW}, {dw, DW}]), | ||
| Options = case Ctx#ctx.timeout of | ||
| undefined -> Options0; | ||
| Else -> Options0 ++ [{timeout, Else}] | ||
| end, | ||
| Result = case wrq:get_req_header(?HEAD_VCLOCK, RD) of | ||
| undefined -> | ||
| C:delete(B,K,Options); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be at debug level and probably have a more useful message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
meant to remove.