Remove problematic clause from maybe_add_last_sample

This commit is contained in:
kjnilsson 2016-11-15 10:38:53 +00:00
parent bf63f53150
commit 2f96ab8236
6 changed files with 82 additions and 40 deletions

View File

@ -54,7 +54,6 @@
add_element/3,
to_list/2,
foldl/5,
normalize/4,
to_normalized_list/5]).
-export([timestamp/0,
@ -365,27 +364,21 @@ maybe_add_last_sample(_Now, #slide{total = T, n = N,
buf1 = [{_, T} | _] = Buf1}) ->
{N, Buf1};
maybe_add_last_sample(Now, #slide{total = T,
interval = I,
n = N,
interval = I,
buf1 = [{TS, _} | _] = Buf1})
when T =/= undefined andalso Now >= (TS + I) ->
{N + 1, [{TS + I, T} | Buf1]};
maybe_add_last_sample(Now, #slide{total = T,
interval = I,
n = N,
buf2 = [{TS, _} | _]})
when T =/= undefined andalso Now >= (TS + I) ->
{N + 1, [{TS + I, T}]};
maybe_add_last_sample(Now, #slide{total = T, interval = I, buf1 = [], buf2 = [], n = N, last = Last})
when T =/= undefined andalso Now > Last + I ->
{N + 1, [{Now, T}]};
when T =/= undefined andalso Now > TS ->
{N + 1, [{min(Now, TS + I), T} | Buf1]};
maybe_add_last_sample(Now, #slide{total = T, buf1 = [], buf2 = []})
when T =/= undefined ->
{1, [{Now, T}]};
maybe_add_last_sample(_Now, #slide{buf1 = Buf1, n = N}) ->
{N, Buf1}.
-spec to_normalized_list(timestamp(), timestamp(), integer(), slide(), no_pad | tuple()) ->
[tuple()].
to_normalized_list(Now, Start, Interval, Slide, Empty) ->
to_normalized_list(Now, Start, Interval, Slide, Empty, fun ceil/1).
to_normalized_list(Now, Start, Interval, Slide, Empty, fun round/1).
to_normalized_list(Now, Start, Interval, #slide{first = FirstTS0,
total = Total,
@ -430,9 +423,10 @@ to_normalized_list(Now, Start, Interval, #slide{first = FirstTS0,
end, {undefined, []}, lists:seq(Start, Now, Interval)),
Res1 ++ Pad.
-spec normalize(timestamp(), timestamp(), non_neg_integer(), slide()) -> slide().
normalize(Now, Start, Interval, Slide) ->
Res = to_normalized_list(Now, Start, Interval, Slide, no_pad),
-spec normalize(timestamp(), timestamp(), non_neg_integer(), slide(), function())
-> slide().
normalize(Now, Start, Interval, Slide, Fun) ->
Res = to_normalized_list(Now, Start, Interval, Slide, no_pad, Fun),
Slide#slide{buf1 = Res, buf2 = [], n = length(Res)}.
%% @doc Normalize an incremental set of slides for summing
@ -441,10 +435,11 @@ normalize(Now, Start, Interval, Slide) ->
%% Discards anything older than Now - Size
%% Fills in blanks in the ideal sequence with the last known value or undefined
%% @end
-spec normalize_incremental_slide(timestamp(), non_neg_integer(), slide()) -> slide().
normalize_incremental_slide(Now, Interval, #slide{size = Size} = Slide) ->
-spec normalize_incremental_slide(timestamp(), non_neg_integer(), slide(), function())
-> slide().
normalize_incremental_slide(Now, Interval, #slide{size = Size} = Slide, Fun) ->
Start = Now - Size,
normalize(Now, Start, Interval, Slide).
normalize(Now, Start, Interval, Slide, Fun).
-spec sum([slide()]) -> slide().
%% @doc Sums a list of slides
@ -467,7 +462,8 @@ sum(Now, [Slide = #slide{interval = Interval, size = Size, incremental = true} |
Value, Dict)
end,
{Total, Dict} = lists:foldl(fun(#slide{total = T} = S, {Tot, Acc}) ->
N = normalize_incremental_slide(Now, Interval, S),
N = normalize_incremental_slide(Now, Interval, S,
fun ceil/1),
Total = add_to_total(T, Tot),
{Total, foldl(Start, Fun, Acc, N#slide{total = undefined})}
end, {undefined, orddict:new()}, All),

View File

@ -70,7 +70,7 @@ lookup_all(Table, Ids, SecondKey) ->
format_range(no_range, Now, Table, Interval, InstantRateFun, _SamplesFun) ->
format_no_range(Table, Now, Interval, InstantRateFun);
format_range(#range{last = Last, first = First, incr = Incr}, _Now, Table,
Interval, InstantRateFun, SamplesFun) ->
Interval, _InstantRateFun, SamplesFun) ->
case SamplesFun() of
not_found ->
[];
@ -81,8 +81,8 @@ format_range(#range{last = Last, first = First, incr = Incr}, _Now, Table,
Slide, Empty)),
Length = length(List),
RangePoint = Last - Interval,
{Total, Rate} = calculate_instant_rate(InstantRateFun, Table,
RangePoint),
LastTwo = get_last_two(List, Length),
{Total, Rate} = calculate_rate(LastTwo, Table, RangePoint),
{Samples, SampleTotals} = format_samples(List, empty(Table, []),
Empty),
format_rate(Table, Total, Rate, Samples, SampleTotals, Length)
@ -133,6 +133,17 @@ calculate_instant_rate(Fun, Table, RangePoint) ->
end
end.
calculate_rate([], Table, _RangePoint) ->
{empty(Table, 0), empty(Table, 0.0)};
calculate_rate([{_, Total} = Last | T], Table, RangePoint) ->
Rate = rate_from_last_increment(Table, Last, T, RangePoint),
{Total, Rate}.
get_last_two(List, Length) when Length =< 2 ->
lists:reverse(List);
get_last_two(List, Length) ->
lists:reverse(lists:nthtail(Length - 2, List)).
get_total(Slide, Table) ->
case exometer_slide:last(Slide) of
undefined -> empty(Table, 0);

View File

@ -90,8 +90,8 @@ incremental_add_element_basics(_Config) ->
[] = exometer_slide:to_list(Now, S0),
% add element before next interval
S1 = exometer_slide:add_element(Now + 10, {1}, S0),
%% to_list is empty
[] = exometer_slide:to_list(Now, S1),
%% to_list is not empty, as we take the 'real' total
[{Now, {1}}] = exometer_slide:to_list(Now, S1),
Then = Now + 101,
% add element after interval
@ -177,7 +177,7 @@ incremental_sum_with_total(_Config) ->
S3 = exometer_slide:sum([S1, S2]),
{10} = exometer_slide:last(S3),
[25,20,15,10,5] = lists:reverse([T || {T, _} <- exometer_slide:to_list(26, S3)]),
[ 9, 7, 5, 3,1] = lists:reverse([V || {_, {V}} <- exometer_slide:to_list(26, S3)]).
[ 10, 7, 5, 3,1] = lists:reverse([V || {_, {V}} <- exometer_slide:to_list(26, S3)]).
foldl_realises_partial_sample(_Config) ->
Now = 0,
@ -319,7 +319,7 @@ to_normalized_list(_Config) ->
[{15, {2}}, {10, {1}}, {5, {1}}],
{5, 15}},
{[{6, 1}, {11, 1}, {16, 1}], % align timestamps with query
[{15, {2}}, {10, {1}}, {5, {0}}, {0, {0}}],
[{15, {3}}, {10, {2}}, {5, {1}}, {0, {0}}],
{0, 15}},
{[{5, 1}, {10, 1}, {15, 1}, {20, 1}, {25, 1}, {30, 1}], % ???
[{30, {6}}, {25, {5}}, {20, {4}}, {15, {3}}], % we cannot possibly deduce what 10 should be

View File

@ -2041,7 +2041,7 @@ rates_test(Config) ->
MsgStats = pget(message_stats, Overview, []),
pget(rate, pget(publish_details, MsgStats, []), 0) > 0
end,
wait_until(Fun, 5),
wait_until(Fun, 60),
Overview = http_get(Config, "/overview"),
MsgStats = pget(message_stats, Overview),
QueueTotals = pget(queue_totals, Overview),

View File

@ -92,7 +92,7 @@ stats_tables() ->
].
sample_size(large) ->
choose(3, 200);
choose(15, 200);
sample_size(small) ->
choose(0, 1).
@ -187,9 +187,10 @@ format_incremental_total_no_range_test(_Config) ->
%% Requests using range
%%---------------------
format_rate_range_test(_Config) ->
%% Request a range bang on the middle, so we ensure no padding is applied
Fun = fun() ->
prop_format(large, rate_check(fun(Rate) -> Rate > 0 end),
false, fun full_range/2)
false, fun middle_range/2)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
@ -204,9 +205,10 @@ format_zero_rate_range_test(_Config) ->
%% Rates for 3 or more monotonically increasing incremental samples will always be > 0
format_incremental_rate_range_test(_Config) ->
%% Request a range bang on the middle, so we ensure no padding is applied
Fun = fun() ->
prop_format(large, rate_check(fun(Rate) -> Rate > 0 end),
true, fun full_range/2)
true, fun middle_range/2)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
@ -403,7 +405,25 @@ get_from_detail(Tag, Detail, Results) ->
proplists:get_value(Tag, proplists:get_value(Detail, Results), []).
full_range(LastTS, Interval) ->
#range{first = 0, last = LastTS, incr = Interval}.
Last = last_ts(0, LastTS, Interval),
#range{first = 0, last = Last, incr = Interval}.
middle_range(LastTS, Interval) ->
Last = last_ts(0, LastTS - Interval, Interval),
#range{first = 0, last = Last, incr = Interval}.
no_range(_LastTS, _Interval) ->
no_range.
%% Generate a well-formed interval from Start using Interval steps
last_ts(First, Last, Interval) ->
ceil(((Last - First) / Interval)) * Interval + First.
ceil(X) when X < 0 ->
trunc(X);
ceil(X) ->
T = trunc(X),
case X - T == 0 of
true -> T;
false -> T + 1
end.

View File

@ -106,25 +106,40 @@ queue_coarse_test1(_Config) ->
First = exometer_slide:timestamp(),
stats_series(fun stats_q/2, [[{test, 1}, {test2, 1}], [{test, 10}], [{test, 20}]]),
Last = exometer_slide:timestamp(),
R = range(First, Last, 1),
Interval = 1,
R = range(First, Last, Interval),
simple_details(get_q(test, R), messages, 20, R),
simple_details(get_vhost(R), messages, 21, R),
simple_details(get_overview_q(R), messages, 21, R),
delete_q(test),
timer:sleep(1150),
Next = exometer_slide:timestamp(),
R1 = range(First, Next, 1),
Next = last_ts(First, Interval),
R1 = range(First, Next, Interval),
simple_details(get_vhost(R1), messages, 1, R1),
simple_details(get_overview_q(R1), messages, 1, R1),
delete_q(test2),
timer:sleep(1150),
Next2 = exometer_slide:timestamp(),
R2 = range(First, Next2, 1),
Next2 = last_ts(First, Interval),
R2 = range(First, Next2, Interval),
simple_details(get_vhost(R2), messages, 0, R2),
simple_details(get_overview_q(R2), messages, 0, R2),
[rabbit_mgmt_metrics_collector:reset_lookups(T) || {T, _} <- ?CORE_TABLES],
ok.
%% Generate a well-formed interval from Start using Interval steps
last_ts(First, Interval) ->
Now = exometer_slide:timestamp(),
ceil(((Now - First) / Interval * 1000)) * Interval + First.
ceil(X) when X < 0 ->
trunc(X);
ceil(X) ->
T = trunc(X),
case X - T == 0 of
true -> T;
false -> T + 1
end.
connection_coarse_test(Config) ->
ok = rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, connection_coarse_test1, [Config]).
@ -134,7 +149,7 @@ connection_coarse_test1(_Config) ->
create_conn(test2),
stats_series(fun stats_conn/2, [[{test, 2}, {test2, 5}], [{test, 5}, {test2, 1}],
[{test, 10}]]),
Last = exometer_slide:timestamp(),
Last = last_ts(First, 5),
R = range(First, Last, 5),
simple_details(get_conn(test, R), recv_oct, 10, R),
simple_details(get_conn(test2, R), recv_oct, 1, R),
@ -163,7 +178,7 @@ fine_stats_aggregation_test1(_Config) ->
channel_series(ch2, [{[{x, 5}], [{q1, x, 15}, {q2, x, 1}], []},
{[{x, 2}], [{q1, x, 10}, {q2, x, 2}], []},
{[{x, 3}], [{q1, x, 25}, {q2, x, 2}], []}]),
timer:sleep(1000),
timer:sleep(2000),
fine_stats_aggregation_test0(true, First),
delete_q(q2),
timer:sleep(5000),