Skip to content

Commit

Permalink
fix list_keys for short keys
Browse files Browse the repository at this point in the history
It appears short keys, as in

  CREATE TABLE t (ts TIMESTAMP NOT NULL, PRIMARY KEY((ts),ts));

don't get sext-encoded, and are instead sent to the calling process
of riak_client:stream_list_keys as tuples, causing the resource streaming
fun to silently choke on sext:decode(Tuple). As a result, the http client
expecting chunked response, receives nothing.

This is probably a bug on the side of riak_kv, which we work around by
explicitly not attempting a sext:decode on tuples.
  • Loading branch information
Andrei Zavada committed Apr 15, 2016
1 parent 1288556 commit 467d814
Showing 1 changed file with 11 additions and 18 deletions.
29 changes: 11 additions & 18 deletions src/riak_kv_wm_timeseries_listkeys.erl
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,7 @@ content_types_provided(RD, Ctx) ->
produce_doc_body(RD, Ctx = #ctx{table = Table, mod = Mod}) ->
{ok, ReqId} = riak_client:stream_list_keys(
{Table, Table}, undefined, {riak_client, [node(), undefined]}),
{{halt, 200}, wrq:set_resp_body({stream, prepare_stream(ReqId, Table, Mod)}, RD), Ctx}.

prepare_stream(ReqId, Table, Mod) ->
{<<"">>, fun() -> stream_keys(ReqId, Table, Mod) end}.
{{stream, {[], fun() -> stream_keys(ReqId, Table, Mod) end}}, RD, Ctx}.

stream_keys(ReqId, Table, Mod) ->
receive
Expand All @@ -151,17 +148,16 @@ stream_keys(ReqId, Table, Mod) ->
{ReqId, {keys, Keys}} ->
{ts_keys_to_body(Keys, Table, Mod), fun() -> stream_keys(ReqId, Table, Mod) end};
{ReqId, done} ->
{<<"">>, done};
{<<>>, done};
{ReqId, {error, timeout}} ->
{mochijson2:encode({struct, [{error, timeout}]}), done};
_Weird ->
%% @todo: should we log this?
stream_keys(ReqId, Table, Mod)
end.

ts_keys_to_body(EncodedKeys, Table, Mod) ->
ts_keys_to_body(Keys, Table, Mod) ->
BaseUrl = base_url(Table),
Keys = decode_keys(EncodedKeys),
KeyTypes = riak_kv_wm_ts_util:local_key_fields_and_types(Mod),
%% Dialyzer issues this warning if the lists:map is replaced with
%% the list comprehension (below):
Expand All @@ -171,20 +167,20 @@ ts_keys_to_body(EncodedKeys, Table, Mod) ->
%% URLs = [format_url(BaseUrl, KeyTypes, Key)
%% || Key <- Keys],

URLs = lists:map(fun(Key) ->
format_url(BaseUrl, KeyTypes, Key)
end,
Keys),
URLs =
lists:map(
fun(Key) when is_tuple(Key) -> %% simple single-field keys like {1}, seen in the wild
format_url(BaseUrl, KeyTypes, tuple_to_list(Key));
(Key) when is_binary(Key) -> %% sext-encoded ones
format_url(BaseUrl, KeyTypes, tuple_to_list(sext:decode(Key)))
end,
Keys),
iolist_to_binary(URLs).


format_url(BaseUrl, KeyTypes, Key) ->
iolist_to_binary([BaseUrl, key_to_string(lists:zip(Key, KeyTypes)), $\n]).

decode_keys(Keys) ->
[tuple_to_list(sext:decode(A))
|| A <- Keys, A /= []].

key_to_string(KFTypes) ->
string:join(
[[Field, $/, mochiweb_util:quote_plus(value_to_url_string(Key, Type))]
Expand All @@ -195,9 +191,6 @@ value_to_url_string(V, varchar) ->
binary_to_list(V);
value_to_url_string(V, sint64) ->
integer_to_list(V);
value_to_url_string(V, double) ->
%% float_to_list(V); %% this would give "1.19999999999999995559e+00" for 1.2
lists:flatten(io_lib:format("~g", [V]));
value_to_url_string(V, timestamp) ->
integer_to_list(V).

Expand Down

0 comments on commit 467d814

Please sign in to comment.