Analysis task page is slow to load
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Jan 2016 22:49:04 +0000 (22:49 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Jan 2016 22:49:04 +0000 (22:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=152517

Reviewed by Andreas Kling.

The slowness comes from r194130 which made the JSON API at /api/analysis-tasks to report the start
and the end of each analysis task. This query was adding ~2s to the total JSON generation time.

Cache these values on analysis_task table since they never change once an analysis task is created.

* init-database.sql: Added columns task_start_run_time and task_end_run_time to analysis_task table.
Also added the missing drop statements at the top.

* public/api/analysis-tasks.php:
(fetch_and_push_bugs_to_tasks): Don't fetch the latest commit time of the start and the end.
(format_task): Report task_start_run_time and task_end_run_time as startRunTime and endRunTime.

* public/privileged-api/create-analysis-task.php:
(main): Set start_run_time and end_run_time when creating an analysis task.
(time_for_run): Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@194611 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Websites/perf.webkit.org/ChangeLog
Websites/perf.webkit.org/init-database.sql
Websites/perf.webkit.org/public/api/analysis-tasks.php
Websites/perf.webkit.org/public/privileged-api/create-analysis-task.php

index 17342d5..a322b79 100644 (file)
@@ -1,3 +1,26 @@
+2015-12-22  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Analysis task page is slow to load
+        https://bugs.webkit.org/show_bug.cgi?id=152517
+
+        Reviewed by Andreas Kling.
+
+        The slowness comes from r194130 which made the JSON API at /api/analysis-tasks to report the start
+        and the end of each analysis task. This query was adding ~2s to the total JSON generation time.
+
+        Cache these values on analysis_task table since they never change once an analysis task is created.
+
+        * init-database.sql: Added columns task_start_run_time and task_end_run_time to analysis_task table.
+        Also added the missing drop statements at the top.
+
+        * public/api/analysis-tasks.php:
+        (fetch_and_push_bugs_to_tasks): Don't fetch the latest commit time of the start and the end.
+        (format_task): Report task_start_run_time and task_end_run_time as startRunTime and endRunTime.
+
+        * public/privileged-api/create-analysis-task.php:
+        (main): Set start_run_time and end_run_time when creating an analysis task.
+        (time_for_run): Added.
+
 2015-12-17  Ryosuke Niwa  <rniwa@webkit.org>
 
         v3 UI shouldn't open/close pane selector by mouseenter/leave
index 088a039..22858f1 100644 (file)
@@ -17,6 +17,8 @@ DROP TABLE reports CASCADE;
 DROP TABLE tracker_repositories CASCADE;
 DROP TABLE bug_trackers CASCADE;
 DROP TABLE analysis_tasks CASCADE;
+DROP TABLE analysis_strategies CASCADE;
+DROP TYPE analysis_task_result_type CASCADE;
 DROP TABLE build_triggerables CASCADE;
 DROP TABLE triggerable_configurations CASCADE;
 DROP TABLE triggerable_repositories CASCADE;
@@ -191,7 +193,9 @@ CREATE TABLE analysis_tasks (
     task_platform integer REFERENCES platforms NOT NULL,
     task_metric integer REFERENCES test_metrics NOT NULL,
     task_start_run integer REFERENCES test_runs,
+    task_start_run_time timestamp,
     task_end_run integer REFERENCES test_runs,
+    task_end_run_time timestamp,
     task_result analysis_task_result_type,
     task_needed boolean,
     CONSTRAINT analysis_task_should_be_unique_for_range UNIQUE(task_start_run, task_end_run),
index bfed71f..e0c8594 100644 (file)
@@ -75,35 +75,6 @@ function fetch_and_push_bugs_to_tasks($db, &$tasks) {
         $task['finishedBuildRequestCount'] = $build_count['finished'];
     }
 
-    $run_ids = array();
-    $task_by_run = array();
-    foreach ($tasks as &$task) {
-        if ($task['startRun']) {
-            array_push($run_ids, $task['startRun']);
-            $task_by_run[$task['startRun']] = &$task;
-        }
-        if ($task['endRun']) {
-            array_push($run_ids, $task['endRun']);
-            $task_by_run[$task['endRun']] = &$task;
-        }
-    }
-
-    // FIXME: This query is quite expensive. We may need to store this directly in analysis_tasks table instead.
-    $build_revision_times = $db->query_and_fetch_all('SELECT run_id, build_time, max(commit_time) AS revision_time
-            FROM builds
-                LEFT OUTER JOIN build_commits ON commit_build = build_id
-                LEFT OUTER JOIN commits ON build_commit = commit_id, test_runs
-            WHERE run_build = build_id AND run_id = ANY($1) GROUP BY build_id, run_id',
-        array('{' . implode(', ', $run_ids) . '}'));
-    foreach ($build_revision_times as &$row) {
-        $time = $row['revision_time'] or $row['build_time'];
-        $id = $row['run_id'];
-        if ($task_by_run[$id]['startRun'] == $id)
-            $task_by_run[$id]['startRunTime'] = Database::to_js_time($time);
-        if ($task_by_run[$id]['endRun'] == $id)
-            $task_by_run[$id]['endRunTime'] = Database::to_js_time($time);
-    }
-
     return $bugs;
 }
 
@@ -118,7 +89,9 @@ function format_task($task_row) {
         'platform' => $task_row['task_platform'],
         'metric' => $task_row['task_metric'],
         'startRun' => $task_row['task_start_run'],
+        'startRunTime' => Database::to_js_time($task_row['task_start_run_time']),
         'endRun' => $task_row['task_end_run'],
+        'endRunTime' => Database::to_js_time($task_row['task_end_run_time']),
         'category' => $task_row['task_result'] ? 'bisecting' : 'unconfirmed',
         'result' => $task_row['task_result'],
         'needed' => $task_row['task_needed'] ? Database::is_true($task_row['task_needed']) : null,
index 0a9d32f..0060a09 100644 (file)
@@ -25,6 +25,11 @@ function main() {
 
     $config = ensure_config_from_runs($db, $start_run, $end_run);
 
+    $start_run_time = time_for_run($db, $start_run_id);
+    $end_run_time = time_for_run($db, $end_run_id);
+    if (!$start_run_time || !$end_run_time)
+        exit_with_error('InvalidTimeRange', array('startTime' => $start_run_time, 'endTime' => $end_run_time));
+
     $db->begin_transaction();
 
     $segmentation_id = NULL;
@@ -57,7 +62,9 @@ function main() {
         'platform' => $config['config_platform'],
         'metric' => $config['config_metric'],
         'start_run' => $start_run_id,
+        'start_run_time' => $start_run_time,
         'end_run' => $end_run_id,
+        'end_run_time' => $end_run_time,
         'segmentation' => $segmentation_id,
         'test_range' => $test_range_id));
     $db->commit_transaction();
@@ -81,6 +88,15 @@ function ensure_config_from_runs($db, $start_run, $end_run) {
     return ensure_row_by_id($db, 'test_configurations', 'config', $start_run['run_config'], 'ConfigNotFound', $range);
 }
 
+function time_for_run($db, $run_id) {
+    $result = $db->query_and_fetch_all('SELECT max(commit_time) as time
+        FROM test_runs JOIN builds ON run_build = build_id
+            JOIN build_commits ON commit_build = build_id
+            JOIN commits ON build_commit = commit_id
+        WHERE run_id = $1', array($run_id));
+    return $result ? $result[0]['time'] : null;
+}
+
 main();
 
 ?>