| 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 |