-
Notifications
You must be signed in to change notification settings - Fork 1
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
Nhse o34 orkv.i58 refactor #59
base: openriak-3.4
Are you sure you want to change the base?
Changes from all commits
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 |
---|---|---|
@@ -1,7 +1,7 @@ | ||
-module(riak_kv_http_cache). | ||
|
||
-export([start_link/0, | ||
get_stats/0]). | ||
get_stats/1]). | ||
|
||
-export([init/1, | ||
handle_call/3, | ||
|
@@ -10,15 +10,19 @@ | |
terminate/2, | ||
code_change/3]). | ||
|
||
-define(SERVER, ?MODULE). | ||
-record(st, | ||
{ | ||
ts :: undefined|erlang:timestamp(), | ||
stats = [] | ||
} | ||
). | ||
|
||
-record(st, {ts, stats = []}). | ||
|
||
start_link() -> | ||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). | ||
|
||
get_stats() -> | ||
gen_server:call(?MODULE, get_stats). | ||
get_stats(Timeout) -> | ||
gen_server:call(?MODULE, get_stats, Timeout). | ||
|
||
init(_) -> | ||
{ok, #st{}}. | ||
|
@@ -40,15 +44,15 @@ code_change(_, S, _) -> | |
{ok, S}. | ||
|
||
check_cache(#st{ts = undefined} = S) -> | ||
S#st{ts = os:timestamp(), stats = do_get_stats()}; | ||
Stats = riak_kv_status:get_stats(web), | ||
S#st{ts = os:timestamp(), stats = Stats}; | ||
check_cache(#st{ts = Then} = S) -> | ||
CacheTime = application:get_env(riak_kv, http_stats_cache_seconds, 1), | ||
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. One could be generous and make the configurable time in milliseconds instead of course seconds. That would help if one ever want to test these timeouts in QuickCheck like fashion. |
||
Now = os:timestamp(), | ||
case timer:now_diff(Now, Then) < 1000000 of | ||
true -> | ||
S; | ||
false -> | ||
S#st{ts = Now, stats = do_get_stats()} | ||
end. | ||
|
||
do_get_stats() -> | ||
riak_kv_wm_stats:get_stats(). | ||
case timer:now_diff(Now, Then) < (CacheTime * 1000000) of | ||
true -> | ||
S; | ||
false -> | ||
Stats = riak_kv_status:get_stats(web), | ||
S#st{ts = os:timestamp(), stats = Stats} | ||
end. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,33 +91,60 @@ get_stats(console) -> | |
++ riak_kv_stat_bc:disk_stats() | ||
++ riak_kv_stat_bc:app_stats(). | ||
|
||
aliases() -> | ||
Grouped = exometer_alias:prefix_foldl( | ||
<<>>, | ||
fun(Alias, Entry, DP, Acc) -> | ||
orddict:append(Entry, {DP, Alias}, Acc) | ||
end, orddict:new()), | ||
lists:keysort( | ||
1, | ||
lists:foldl( | ||
fun({K, DPs}, Acc) -> | ||
case exometer:get_value(K, [D || {D,_} <- DPs]) of | ||
{ok, Vs} when is_list(Vs) -> | ||
lists:foldr(fun({D,V}, Acc1) -> | ||
{_,N} = lists:keyfind(D,1,DPs), | ||
[{N,V}|Acc1] | ||
end, Acc, Vs); | ||
Other -> | ||
Val = case Other of | ||
{ok, disabled} -> undefined; | ||
_ -> 0 | ||
end, | ||
lists:foldr(fun({_,N}, Acc1) -> | ||
[{N,Val}|Acc1] | ||
end, Acc, DPs) | ||
end | ||
end, [], orddict:to_list(Grouped))). | ||
|
||
aliases() -> | ||
AllStats = | ||
exometer_alias:prefix_foldl( | ||
<<>>, | ||
fun(Alias, Entry, DP, Acc) -> [{Entry, {DP, Alias}}|Acc] end, | ||
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. Later on we make an assumption on how these entries are kind of sorted such that consecutive entries end up next to each other, right? |
||
[] | ||
), | ||
case AllStats of | ||
[] -> | ||
[]; | ||
AllStats when is_list(AllStats) -> | ||
{{FinalEntry, FinalDPMap}, AliasVals} = | ||
lists:foldl( | ||
fun({Entry, {DP, Alias}}, {{PrevEntry, DPmap}, Acc}) -> | ||
case Entry of | ||
Entry when Entry == PrevEntry -> | ||
{{PrevEntry, maps:put(DP, Alias, DPmap)}, Acc}; | ||
Entry when PrevEntry == none -> | ||
{{Entry, maps:put(DP, Alias, DPmap)}, Acc}; | ||
Entry -> | ||
UpdAcc = get_exometer_values(PrevEntry, DPmap), | ||
{{Entry, #{DP => Alias}}, UpdAcc ++ Acc} | ||
end | ||
end, | ||
{{none, #{}}, []}, | ||
AllStats | ||
), | ||
lists:keysort( | ||
1, | ||
get_exometer_values(FinalEntry, FinalDPMap) ++ AliasVals | ||
) | ||
end. | ||
|
||
get_exometer_values(Entry, DPmap) -> | ||
case exometer:get_value(Entry, maps:keys(DPmap)) of | ||
{ok, Vs} when is_list(Vs) -> | ||
lists:map( | ||
fun({D, V}) -> | ||
{maps:get(D, DPmap), V} | ||
end, | ||
Vs | ||
); | ||
Other -> | ||
DefaultValue = | ||
case Other of | ||
{ok, disabled} -> disabled; | ||
_ -> 0 | ||
end, | ||
lists:map( | ||
fun(A) -> {A, DefaultValue} end, | ||
maps:values(DPmap) | ||
) | ||
end. | ||
|
||
expand_disk_stats([{disk, Stats}]) -> | ||
[{disk, [{struct, [{id, list_to_binary(Id)}, {size, Size}, {used, Used}]} | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -29,14 +29,17 @@ | |||||
content_types_provided/2, | ||||||
service_available/2, | ||||||
forbidden/2, | ||||||
malformed_request/2, | ||||||
produce_body/2, | ||||||
pretty_print/2 | ||||||
]). | ||||||
-export([get_stats/0]). | ||||||
|
||||||
-define(TIMEOUT, 30000). | ||||||
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. with comment:
Suggested change
|
||||||
|
||||||
-include_lib("webmachine/include/webmachine.hrl"). | ||||||
-include("riak_kv_wm_raw.hrl"). | ||||||
|
||||||
-record(ctx, {}). | ||||||
-record(ctx, {timeout = ?TIMEOUT :: non_neg_integer()}). | ||||||
|
||||||
init(_) -> | ||||||
{ok, #ctx{}}. | ||||||
|
@@ -66,25 +69,67 @@ content_types_provided(ReqData, Context) -> | |||||
{"text/plain", pretty_print}], | ||||||
ReqData, Context}. | ||||||
|
||||||
|
||||||
service_available(ReqData, Ctx) -> | ||||||
{true, ReqData, Ctx}. | ||||||
|
||||||
malformed_request(RD, Ctx) -> | ||||||
case wrq:get_qs_value("timeout", RD) of | ||||||
undefined -> | ||||||
{false, RD, Ctx}; | ||||||
TimeoutStr -> | ||||||
try | ||||||
case list_to_integer(TimeoutStr) of | ||||||
Timeout when Timeout > 0 -> | ||||||
{false, RD, Ctx#ctx{timeout=Timeout}} | ||||||
end | ||||||
catch | ||||||
_:_ -> | ||||||
{true, | ||||||
wrq:append_to_resp_body( | ||||||
io_lib:format( | ||||||
"Bad timeout value ~0p", | ||||||
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. Add in explanation "should be provided in miliseconds" |
||||||
[TimeoutStr] | ||||||
), | ||||||
wrq:set_resp_header(?HEAD_CTYPE, "text/plain", RD)), | ||||||
Ctx} | ||||||
end | ||||||
end. | ||||||
|
||||||
forbidden(RD, Ctx) -> | ||||||
{riak_kv_wm_utils:is_forbidden(RD), RD, Ctx}. | ||||||
|
||||||
produce_body(ReqData, Ctx) -> | ||||||
Stats= riak_kv_http_cache:get_stats(), | ||||||
Body = mochijson2:encode({struct, Stats}), | ||||||
{Body, ReqData, Ctx}. | ||||||
produce_body(RD, Ctx) -> | ||||||
try | ||||||
Stats = riak_kv_http_cache:get_stats(Ctx#ctx.timeout), | ||||||
Body = mochijson2:encode({struct, Stats}), | ||||||
{Body, RD, Ctx} | ||||||
catch | ||||||
exit:{timeout, _} -> | ||||||
{ | ||||||
{halt, 503}, | ||||||
wrq:set_resp_header( | ||||||
?HEAD_CTYPE, | ||||||
"text/plain", | ||||||
wrq:append_to_response_body( | ||||||
io_lib:format( | ||||||
"Request timed out after ~w ms", | ||||||
[Ctx#ctx.timeout] | ||||||
), | ||||||
RD | ||||||
) | ||||||
), | ||||||
Ctx | ||||||
} | ||||||
end. | ||||||
|
||||||
%% @spec pretty_print(webmachine:wrq(), context()) -> | ||||||
%% {string(), webmachine:wrq(), context()} | ||||||
%% @doc Format the respons JSON object is a "pretty-printed" style. | ||||||
pretty_print(RD1, C1=#ctx{}) -> | ||||||
{Json, RD2, C2} = produce_body(RD1, C1), | ||||||
{json_pp:print(binary_to_list(list_to_binary(Json))), RD2, C2}. | ||||||
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. Was the reason to do this that Json can be a deeplist and it is flattened in this way to make |
||||||
|
||||||
pretty_print(RD, Ctx) -> | ||||||
case produce_body(RD, Ctx) of | ||||||
{{halt, RepsonseCode}, UpdRD, UpdCtx} -> | ||||||
{{halt, RepsonseCode}, UpdRD, UpdCtx}; | ||||||
{Json, UpdRD, UpdCtx} -> | ||||||
{json_pp:print(Json), UpdRD, UpdCtx} | ||||||
end. | ||||||
|
||||||
get_stats() -> | ||||||
riak_kv_status:get_stats(web). |
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.
Would be nice with either a type or a comment stating in which unit the Timeout is given.
-spec get_stats(Milliseconds :: non_neg_integer()) -> .....
or similar