Skip to content

Commit 5d107ee

Browse files
hmmrAndriy Zavada
authored andcommitted
aae_progress_report and other functions needed for Tictac AAE CLI treestatus subcommand (#4)
* aae_schedulenextrebuild/2 * get/setters of various state fields needed for riak admin tictacaae * touch object_splitfun directly for purposes of get/setting storeheads this, to avoid introducing dependency on riak_kv, where riak_object:aae_from_object_binary/1 lives, which actually creates the object_splitfun function. * ct test for get/set_rebuild_schedule * ct for get/set_storeheads * uncomment, unbreak other tests in basic_SUITE * remove extra, redundant steps in get_set_storeheads * avoid exposing internal pids, do produce_aae_progress_report on site * more expressive function names for aae progress report work * aae_schedulenextrebuild/2 better named aae_prompt_nextrebuild * avoid passing entire state record for funs that only need some fields * prompt_nextrebuild done right, with a test * callers of produce_report should assume key_store is always a good pid * splitfun get/set ct test --------- Co-authored-by: Andriy Zavada <andriy.zavada@tiot.jp>
1 parent 1632dfe commit 5d107ee

5 files changed

Lines changed: 366 additions & 71 deletions

File tree

src/aae_controller.erl

Lines changed: 101 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,40 +17,46 @@
1717
-include("include/aae.hrl").
1818

1919
-export([init/1,
20-
handle_call/3,
21-
handle_cast/2,
22-
handle_info/2,
23-
terminate/2,
24-
code_change/3]).
20+
handle_call/3,
21+
handle_cast/2,
22+
handle_info/2,
23+
terminate/2,
24+
code_change/3]).
2525

2626
-export([aae_start/6,
27-
aae_start/7,
28-
aae_start/8,
29-
aae_nextrebuild/1,
30-
aae_put/7,
31-
aae_close/1,
32-
aae_destroy/1,
33-
aae_fetchroot/3,
34-
aae_mergeroot/3,
35-
aae_fetchbranches/4,
36-
aae_mergebranches/4,
37-
aae_fetchclocks/5,
38-
aae_fetchclocks/7,
39-
aae_rebuildtrees/5,
40-
aae_rebuildtrees/4,
41-
aae_rebuildstore/2,
42-
aae_rebuildstore/3,
43-
aae_fold/6,
44-
aae_fold/8,
45-
aae_bucketlist/1,
46-
aae_loglevel/2,
47-
aae_ping/3,
48-
aae_runnerprompt/1
27+
aae_start/7,
28+
aae_start/8,
29+
aae_nextrebuild/1,
30+
aae_set_rebuild_schedule/2,
31+
aae_get_rebuild_schedule/1,
32+
aae_prompt_nextrebuild/2,
33+
aae_get_object_splitfun/1,
34+
aae_set_object_splitfun/2,
35+
aae_put/7,
36+
aae_close/1,
37+
aae_destroy/1,
38+
aae_fetchroot/3,
39+
aae_mergeroot/3,
40+
aae_fetchbranches/4,
41+
aae_mergebranches/4,
42+
aae_fetchclocks/5,
43+
aae_fetchclocks/7,
44+
aae_rebuildtrees/5,
45+
aae_rebuildtrees/4,
46+
aae_rebuildstore/2,
47+
aae_rebuildstore/3,
48+
aae_fold/6,
49+
aae_fold/8,
50+
aae_bucketlist/1,
51+
aae_loglevel/2,
52+
aae_ping/3,
53+
aae_runnerprompt/1,
54+
aae_produce_progress_report/1
4955
]).
5056

5157
-export([foldobjects_buildtrees/2,
52-
hash_clocks/2,
53-
wrapped_splitobjfun/1]).
58+
hash_clocks/2,
59+
wrapped_splitobjfun/1]).
5460

5561
-export([wait_on_sync/5]).
5662

@@ -215,6 +221,37 @@ aae_start(
215221
aae_nextrebuild(Pid) ->
216222
gen_server:call(Pid, rebuild_time, ?SYNC_TIMEOUT).
217223

224+
-spec aae_prompt_nextrebuild(pid(), non_neg_integer()) -> ok.
225+
%% @doc
226+
%% Set the next_rebuild time to now + given delay
227+
aae_prompt_nextrebuild(Pid, Delay) ->
228+
gen_server:call(Pid, {prompt_nextrebuild, Delay}, ?SYNC_TIMEOUT).
229+
230+
-spec aae_get_rebuild_schedule(pid()) -> rebuild_schedule().
231+
%% @doc
232+
%% Get rebuild schedule
233+
aae_get_rebuild_schedule(Pid) ->
234+
gen_server:call(Pid, get_rebuild_schedule, ?SYNC_TIMEOUT).
235+
236+
-spec aae_set_rebuild_schedule(pid(), rebuild_schedule()) -> ok.
237+
%% @doc
238+
%% Set rebuild schedule
239+
aae_set_rebuild_schedule(Pid, RS) ->
240+
gen_server:call(Pid, {set_rebuild_schedule, RS}, ?SYNC_TIMEOUT).
241+
242+
-spec aae_get_object_splitfun(pid()) -> function().
243+
%% @doc
244+
%% Get object_splitfun field. It is only used to infer the value of 'storeheads'.
245+
aae_get_object_splitfun(Pid) ->
246+
gen_server:call(Pid, get_object_splitfun, ?SYNC_TIMEOUT).
247+
248+
-spec aae_set_object_splitfun(pid(), function()) -> ok.
249+
%% @doc
250+
%% Set object_splitfun. Used to emulate re-initing the controller
251+
%% with a different value of 'storeheads'.
252+
aae_set_object_splitfun(Pid, A) ->
253+
gen_server:call(Pid, {set_object_splitfun, A}, ?SYNC_TIMEOUT).
254+
218255
-spec aae_put(
219256
pid(),
220257
responsible_preflist(),
@@ -481,6 +518,15 @@ aae_ping(Pid, RequestTime, From) ->
481518
aae_runnerprompt(Pid) ->
482519
gen_server:cast(Pid, runner_prompt).
483520

521+
-spec aae_produce_progress_report(pid()) -> list({atom(), term()}).
522+
%% @doc
523+
%% Generate a 'progress report', with items such as status,
524+
%% last_rebuild, next_rebuild, for the aae controller handling this
525+
%% partition. This report can be displayed by `riak admin tictacaae
526+
%% treestatus` command.
527+
aae_produce_progress_report(Pid) ->
528+
gen_server:call(Pid, produce_report).
529+
484530

485531
%%%============================================================================
486532
%%% gen_server callbacks
@@ -585,6 +631,17 @@ init([Opts]) ->
585631

586632
handle_call(rebuild_time, _From, State) ->
587633
{reply, State#state.next_rebuild, State};
634+
handle_call(get_rebuild_schedule, _From, State = #state{rebuild_schedule = RS}) ->
635+
{reply, RS, State};
636+
handle_call({set_rebuild_schedule, RS}, _From, State) ->
637+
{reply, ok, State#state{rebuild_schedule = RS}};
638+
handle_call(get_object_splitfun, _From, State = #state{object_splitfun = A}) ->
639+
{reply, A, State};
640+
handle_call({set_object_splitfun, A}, _From, State) ->
641+
{reply, ok, State#state{object_splitfun = A}};
642+
handle_call({prompt_nextrebuild, SecsFromNow}, _From, State) ->
643+
{Mega, Sec, Micros} = os:timestamp(),
644+
{reply, ok, State#state{next_rebuild = {Mega, Sec + SecsFromNow, Micros}}};
588645
handle_call(close, _From, State) ->
589646
ok = maybe_flush_puts(State#state.key_store,
590647
State#state.objectspecs_queue,
@@ -945,6 +1002,11 @@ handle_call(bucket_list, _From, State) ->
9451002
true),
9461003
R = aae_keystore:store_bucketlist(State#state.key_store),
9471004
{reply, R, State};
1005+
handle_call(produce_report, _From, State = #state{key_store = KeyStore,
1006+
next_rebuild = NextRebuild,
1007+
tree_caches = TreeCaches}) ->
1008+
R = produce_report(KeyStore, NextRebuild, TreeCaches),
1009+
{reply, R, State};
9481010
handle_call({ping, RequestTime}, _From, State) ->
9491011
T = max(0, timer:now_diff(os:timestamp(), RequestTime)),
9501012
aae_util:log(aae15, [T div 1000], State#state.log_levels),
@@ -1154,6 +1216,16 @@ wrapped_splitobjfun(ObjectSplitFun) ->
11541216
end
11551217
end.
11561218

1219+
produce_report(KeyStore, NextRebuild, TreeCaches) ->
1220+
TotalDirtySegments =
1221+
lists:sum(
1222+
[aae_treecache:cache_segment_count(P) || {_, P} <- TreeCaches]),
1223+
[{last_rebuild, aae_keystore:store_last_rebuild(KeyStore)},
1224+
{next_rebuild, NextRebuild},
1225+
{total_dirty_segments, TotalDirtySegments}
1226+
].
1227+
1228+
11571229
%%%============================================================================
11581230
%%% Internal functions
11591231
%%%============================================================================

src/aae_keystore.erl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
store_fold/8,
5959
store_fetchclock/3,
6060
store_bucketlist/1,
61+
store_last_rebuild/1,
6162
store_loglevel/2
6263
]
6364
).
@@ -442,6 +443,12 @@ store_fetchclock(Pid, Bucket, Key) ->
442443
store_bucketlist(Pid) ->
443444
gen_fsm:sync_send_all_state_event(Pid, bucket_list, infinity).
444445

446+
-spec store_last_rebuild(pid()) -> erlang:timestamp() | never.
447+
%% @doc
448+
%% Get the last rebuild time
449+
store_last_rebuild(Pid) ->
450+
gen_fsm:sync_send_all_state_event(Pid, last_rebuild, infinity).
451+
445452
-spec store_loglevel(pid(), aae_util:log_levels()) -> ok.
446453
%% @doc
447454
%% Alter the log level at runtime
@@ -670,6 +677,8 @@ native({prompt, rebuild_complete}, State) ->
670677
handle_sync_event(bucket_list, _From, StateName, State) ->
671678
Folder = bucket_list(State#state.store_type, State#state.store),
672679
{reply, Folder, StateName, State};
680+
handle_sync_event(last_rebuild, _From, StateName, State = #state{last_rebuild = A}) ->
681+
{reply, A, StateName, State};
673682
handle_sync_event(current_status, _From, StateName, State) ->
674683
{reply, {StateName, State#state.current_guid}, StateName, State};
675684
handle_sync_event(ping, _From, StateName, State) ->
@@ -1291,7 +1300,6 @@ disklog_filename(RootPath, GUID) ->
12911300
filename:join(RootPath, GUID ++ ?DISKLOG_EXT).
12921301

12931302

1294-
12951303
%%%============================================================================
12961304
%%% Test
12971305
%%%============================================================================
@@ -1859,4 +1867,4 @@ generate_objectspecs(Op, B, KeyList) ->
18591867

18601868

18611869

1862-
-endif.
1870+
-endif.

src/aae_treecache.erl

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,18 @@
1717
format_status/1]).
1818

1919
-export([cache_open/3,
20-
cache_new/3,
21-
cache_alter/4,
22-
cache_root/1,
23-
cache_leaves/2,
24-
cache_markdirtysegments/3,
25-
cache_replacedirtysegments/3,
26-
cache_destroy/1,
27-
cache_startload/1,
28-
cache_completeload/2,
29-
cache_loglevel/2,
30-
cache_close/1]).
20+
cache_new/3,
21+
cache_alter/4,
22+
cache_root/1,
23+
cache_leaves/2,
24+
cache_markdirtysegments/3,
25+
cache_replacedirtysegments/3,
26+
cache_destroy/1,
27+
cache_startload/1,
28+
cache_completeload/2,
29+
cache_loglevel/2,
30+
cache_close/1,
31+
cache_segment_count/1]).
3132

3233
-define(PENDING_EXT, ".pnd").
3334
-define(FINAL_EXT, ".aae").
@@ -85,6 +86,12 @@ cache_new(RootPath, PartitionID, LogLevels) ->
8586
cache_destroy(AAECache) ->
8687
gen_server:cast(AAECache, destroy).
8788

89+
-spec cache_segment_count(pid()) -> non_neg_integer().
90+
%% @doc
91+
%% Expose dirty_segments length, for aae-progress-report.
92+
cache_segment_count(AAECache) ->
93+
gen_server:call(AAECache, segment_count, ?SYNC_TIMEOUT).
94+
8895
-spec cache_close(pid()) -> ok.
8996
%% @doc
9097
%% Close a cache with saving
@@ -193,14 +200,16 @@ init([Opts]) ->
193200
},
194201
hibernate
195202
}.
196-
203+
197204

198205
handle_call(is_restored, _From, State) ->
199206
{reply, State#state.is_restored, State};
200207
handle_call(fetch_root, _From, State) ->
201208
{reply, leveled_tictac:fetch_root(State#state.tree), State};
202209
handle_call({fetch_leaves, BranchIDs}, _From, State) ->
203210
{reply, leveled_tictac:fetch_leaves(State#state.tree, BranchIDs), State};
211+
handle_call(segment_count, _From, State = #state{dirty_segments = A}) ->
212+
{reply, length(A), State};
204213
handle_call(close, _From, State) ->
205214
case State#state.safe_save of
206215
true ->
@@ -866,4 +875,4 @@ test_setup_funs(InitialKeys) ->
866875
{AddFun, AlterFun, RemoveFun}.
867876

868877

869-
-endif.
878+
-endif.

0 commit comments

Comments
 (0)