From 19017b3612b4567ced3b8ac9cfe816e6cf80e0f8 Mon Sep 17 00:00:00 2001 From: Robert Newson Date: Wed, 14 Nov 2012 19:32:23 +0000 Subject: Backport new /_active_tasks API Improved _active_tasks API Tasks are now free to set any properties they wish (as an Erlang proplist). Different tasks can have different properties and the status string doesn't exist anymore - instead client applications can build it using more granular properties from _active_tasks. Some of these properties are: 1) "progress" (an integer percentage, for all tasks) 2) "database" (for compactions and indexer tasks) 3) "design_document" (for indexer and view compaction tasks) 4) "source" and "target" (for replications) 5) "docs_read", "docs_written", "doc_write_failures", "missing_revs_found", "missing_revs_checked", "source_seq", "checkpointed_source_seq" and "continuous" for replications BugzID: 14269 Conflicts: apps/couch/src/couch_db_updater.erl apps/couch/src/couch_rep.erl apps/couch/src/couch_task_status.erl apps/couch/src/couch_view_compactor.erl apps/couch/src/couch_view_updater.erl --- apps/couch/test/etap/090-task-status.t | 169 +++++++++++++++++++++++---------- 1 file changed, 121 insertions(+), 48 deletions(-) (limited to 'apps/couch/test') diff --git a/apps/couch/test/etap/090-task-status.t b/apps/couch/test/etap/090-task-status.t index b278de7f..34855834 100755 --- a/apps/couch/test/etap/090-task-status.t +++ b/apps/couch/test/etap/090-task-status.t @@ -15,7 +15,7 @@ main(_) -> test_util:init_code_path(), - etap:plan(16), + etap:plan(28), case (catch test()) of ok -> etap:end_tests(); @@ -25,7 +25,7 @@ main(_) -> end, ok. -check_status(Pid,ListPropLists) -> +get_task_prop(Pid, Prop) -> From = list_to_binary(pid_to_list(Pid)), Element = lists:foldl( fun(PropList,Acc) -> @@ -36,18 +36,28 @@ check_status(Pid,ListPropLists) -> [] end end, - [], ListPropLists + [], couch_task_status:all() ), - couch_util:get_value(status,hd(Element)). + case couch_util:get_value(Prop, hd(Element), nil) of + nil -> + etap:bail("Could not get property '" ++ couch_util:to_list(Prop) ++ + "' for task " ++ pid_to_list(Pid)); + Value -> + Value + end. + +now_ts() -> + {Mega, Secs, _} = erlang:now(), + Mega * 1000000 + Secs. loop() -> receive - {add, From} -> - Resp = couch_task_status:add_task("type", "task", "init"), + {add, Props, From} -> + Resp = couch_task_status:add_task(Props), From ! {ok, self(), Resp}, loop(); - {update, Status, From} -> - Resp = couch_task_status:update(Status), + {update, Props, From} -> + Resp = couch_task_status:update(Props), From ! {ok, self(), Resp}, loop(); {update_frequency, Msecs, From} -> @@ -82,96 +92,159 @@ test() -> Pid2 = spawn(TaskUpdater), Pid3 = spawn(TaskUpdater), - ok = call(Pid1, add), + ok = call(Pid1, add, [{type, replication}, {progress, 0}]), etap:is( length(couch_task_status:all()), 1, "Started a task" ), + Task1StartTime = get_task_prop(Pid1, started_on), + etap:is( + is_integer(Task1StartTime), + true, + "Task start time is defined." + ), + etap:is( + get_task_prop(Pid1, updated_on), + Task1StartTime, + "Task's start time is the same as the update time before an update." + ), etap:is( - call(Pid1, add), + call(Pid1, add, [{type, compaction}, {progress, 0}]), {add_task_error, already_registered}, "Unable to register multiple tasks for a single Pid." ), etap:is( - check_status(Pid1, couch_task_status:all()), - <<"init">>, - "Task status was set to 'init'." + get_task_prop(Pid1, type), + replication, + "Task type is 'replication'." ), - - call(Pid1,update,"running"), etap:is( - check_status(Pid1,couch_task_status:all()), - <<"running">>, - "Status updated to 'running'." + get_task_prop(Pid1, progress), + 0, + "Task progress is 0." ), + ok = timer:sleep(1000), + call(Pid1, update, [{progress, 25}]), + etap:is( + get_task_prop(Pid1, progress), + 25, + "Task progress is 25." + ), + etap:is( + get_task_prop(Pid1, updated_on) > Task1StartTime, + true, + "Task's last update time has increased after an update." + ), - call(Pid2,add), + call(Pid2, add, [{type, compaction}, {progress, 0}]), etap:is( length(couch_task_status:all()), 2, "Started a second task." ), - + Task2StartTime = get_task_prop(Pid2, started_on), + etap:is( + is_integer(Task2StartTime), + true, + "Second task's start time is defined." + ), etap:is( - check_status(Pid2, couch_task_status:all()), - <<"init">>, - "Second tasks's status was set to 'init'." + get_task_prop(Pid2, updated_on), + Task2StartTime, + "Second task's start time is the same as the update time before an update." ), - call(Pid2, update, "running"), etap:is( - check_status(Pid2, couch_task_status:all()), - <<"running">>, - "Second task's status updated to 'running'." + get_task_prop(Pid2, type), + compaction, + "Second task's type is 'compaction'." + ), + etap:is( + get_task_prop(Pid2, progress), + 0, + "Second task's progress is 0." ), + ok = timer:sleep(1000), + call(Pid2, update, [{progress, 33}]), + etap:is( + get_task_prop(Pid2, progress), + 33, + "Second task's progress updated to 33." + ), + etap:is( + get_task_prop(Pid2, updated_on) > Task2StartTime, + true, + "Second task's last update time has increased after an update." + ), - call(Pid3, add), + call(Pid3, add, [{type, indexer}, {progress, 0}]), etap:is( length(couch_task_status:all()), 3, "Registered a third task." ), - + Task3StartTime = get_task_prop(Pid3, started_on), + etap:is( + is_integer(Task3StartTime), + true, + "Third task's start time is defined." + ), etap:is( - check_status(Pid3, couch_task_status:all()), - <<"init">>, - "Third tasks's status was set to 'init'." + get_task_prop(Pid3, updated_on), + Task3StartTime, + "Third task's start time is the same as the update time before an update." ), - call(Pid3, update, "running"), etap:is( - check_status(Pid3, couch_task_status:all()), - <<"running">>, - "Third task's status updated to 'running'." + get_task_prop(Pid3, type), + indexer, + "Third task's type is 'indexer'." + ), + etap:is( + get_task_prop(Pid3, progress), + 0, + "Third task's progress is 0." ), + ok = timer:sleep(1000), + call(Pid3, update, [{progress, 50}]), + etap:is( + get_task_prop(Pid3, progress), + 50, + "Third task's progress updated to 50." + ), + etap:is( + get_task_prop(Pid3, updated_on) > Task3StartTime, + true, + "Third task's last update time has increased after an update." + ), call(Pid3, update_frequency, 500), - call(Pid3, update, "still running"), + call(Pid3, update, [{progress, 66}]), etap:is( - check_status(Pid3, couch_task_status:all()), - <<"still running">>, - "Third task's status updated to 'still running'." + get_task_prop(Pid3, progress), + 66, + "Third task's progress updated to 66." ), - call(Pid3, update, "skip this update"), + call(Pid3, update, [{progress, 67}]), etap:is( - check_status(Pid3, couch_task_status:all()), - <<"still running">>, - "Status update dropped because of frequency limit." + get_task_prop(Pid3, progress), + 66, + "Task update dropped because of frequency limit." ), call(Pid3, update_frequency, 0), - call(Pid3, update, "don't skip"), + call(Pid3, update, [{progress, 77}]), etap:is( - check_status(Pid3, couch_task_status:all()), - <<"don't skip">>, - "Status updated after reseting frequency limit." + get_task_prop(Pid3, progress), + 77, + "Task updated after reseting frequency limit." ), -- cgit v1.2.3