OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 /** Random constants. */ | |
6 var MAX_BUILD_STATUS_LENGTH = 50; | |
7 var TICKS_BETWEEN_REFRESHES = 60; | |
8 var NUM_PREVIOUS_BUILDS_TO_SHOW = 3; | |
9 var MAX_MILLISECONDS_TO_WAIT = 5 * 60 * 1000; | |
10 | |
11 /** Parsed JSON data. */ | |
12 var gWaterfallData = []; | |
13 var gStatusData = []; | |
14 var gWaterfallDataIsDirty = true; | |
15 | |
16 /** Global state. */ | |
17 var gTicksUntilRefresh = TICKS_BETWEEN_REFRESHES; | |
18 | |
19 /** Statistics. */ | |
20 var gNumRequestsInFlight = 0; | |
21 var gNumRequestsIgnored = 0; | |
22 var gNumRequestsRetried = 0; | |
23 var gStartTimestamp = 0; | |
24 | |
25 /** Cut the status message down so it doesn't hog the whole screen. */ | |
26 function truncateStatusText(text) { | |
27 if (text.length > MAX_BUILD_STATUS_LENGTH) { | |
28 return text.substr(0, MAX_BUILD_STATUS_LENGTH) + '...'; | |
29 } | |
30 return text; | |
31 } | |
32 | |
33 /** Queries all of the servers for their latest statuses. */ | |
34 function queryServersForInfo() { | |
35 for (var index = 0; index < gWaterfallData.length; ++index) { | |
36 gWaterfallData[index].requestJson(); | |
37 } | |
38 | |
39 for (var index = 0; index < gStatusData.length; ++index) { | |
40 gStatusData[index].requestJson(); | |
41 } | |
42 } | |
43 | |
44 /** Updates the sidebar's contents. */ | |
45 function updateSidebarHTML() { | |
46 // Update all of the project info. | |
47 var divElement = document.getElementById('sidebar-contents'); | |
48 while (divElement.firstChild) { | |
49 divElement.removeChild(divElement.firstChild); | |
50 } | |
51 | |
52 for (var i = 0; i < gStatusData.length; ++i) { | |
53 divElement.appendChild(gStatusData[i].createHtml()); | |
54 } | |
55 | |
56 // Debugging stats. | |
57 document.getElementById('num-ticks-until-refresh').innerHTML = | |
58 gTicksUntilRefresh; | |
59 document.getElementById('num-requests-in-flight').innerHTML = | |
60 gNumRequestsInFlight; | |
61 document.getElementById('num-requests-ignored').innerHTML = | |
62 gNumRequestsIgnored; | |
63 document.getElementById('num-requests-retried').innerHTML = | |
64 gNumRequestsRetried; | |
65 } | |
66 | |
67 /** | |
68 * Organizes all of the bots by category, then alphabetically within their | |
69 * categories. | |
70 */ | |
71 function sortBotNamesByCategory(botInfo) { | |
72 // Bucket all of the bots according to their category. | |
73 var allBotNames = Object.keys(botInfo); | |
74 var bucketedNames = {}; | |
75 for (var i = 0; i < allBotNames.length; ++i) { | |
76 var botName = allBotNames[i]; | |
77 var category = botInfo[botName].category; | |
78 | |
79 if (!bucketedNames[category]) bucketedNames[category] = []; | |
80 bucketedNames[category].push(botName); | |
81 } | |
82 | |
83 // Alphabetically sort bots within their buckets, then append them to the | |
84 // current list. | |
85 var sortedBotNames = []; | |
86 var allCategories = Object.keys(bucketedNames); | |
87 allCategories.sort(); | |
88 for (var i = 0; i < allCategories.length; ++i) { | |
89 var category = allCategories[i]; | |
90 var bucketBots = bucketedNames[category]; | |
91 bucketBots.sort(); | |
92 | |
93 for (var j = 0; j < bucketBots.length; ++j) { | |
94 sortedBotNames.push(bucketBots[j]); | |
95 } | |
96 } | |
97 | |
98 return sortedBotNames; | |
99 } | |
100 | |
101 /** Update all the waterfall data. */ | |
102 function updateStatusHTML() { | |
103 var table = document.getElementById('build-info'); | |
104 while (table.rows.length > 0) { | |
105 table.deleteRow(-1); | |
106 } | |
107 | |
108 for (var i = 0; i < gWaterfallData.length; ++i) { | |
109 gWaterfallData[i].updateWaterfallStatusHTML(); | |
110 } | |
111 } | |
112 | |
113 /** Marks the waterfall data as dirty due to updated filter. */ | |
114 function filterUpdated() { | |
115 gWaterfallDataIsDirty = true; | |
116 } | |
117 | |
118 /** Update the page content. */ | |
119 function updateContent() { | |
120 if (--gTicksUntilRefresh <= 0) { | |
121 gTicksUntilRefresh = TICKS_BETWEEN_REFRESHES; | |
122 queryServersForInfo(); | |
123 } | |
124 | |
125 // Redraw the page content. | |
126 if (gWaterfallDataIsDirty) { | |
127 gWaterfallDataIsDirty = false; | |
128 updateStatusHTML(); | |
129 | |
130 if (document.getElementById('failure-info')) { | |
131 updateCorrelationsHTML(); | |
132 } | |
133 } | |
134 updateSidebarHTML(); | |
135 } | |
136 | |
137 /** Initialize all the things. */ | |
138 function initialize() { | |
139 var gStartTimestamp = new Date().getTime(); | |
140 | |
141 // Initialize the waterfall pages. | |
142 for (var i = 0; i < kBuilderPages.length; ++i) { | |
143 gWaterfallData.push(new WaterfallInfo(kBuilderPages[i])); | |
144 } | |
145 | |
146 // Initialize the status pages. | |
147 for (var i = 0; i < kStatusPages.length; ++i) { | |
148 gStatusData.push(new StatusPageInfo(kStatusPages[i][0], | |
149 kStatusPages[i][1])); | |
150 } | |
151 | |
152 // Kick off the main loops. | |
153 queryServersForInfo(); | |
154 updateStatusHTML(); | |
155 setInterval('updateContent()', 1000); | |
156 } | |
OLD | NEW |