Fixes of perfromance server
This commit is contained in:
+13
-10
@@ -82,17 +82,20 @@ private def uploadBenchmarkResultToBintray(String fileName) {
|
||||
}
|
||||
|
||||
task registerBuild(type: BuildRegister) {
|
||||
onlyBranch = project.findProperty('kotlin.register.branch')
|
||||
// Get bundle size.
|
||||
bundleSize = null
|
||||
if (project.findProperty('kotlin.bundleBuild') != null) {
|
||||
def dist = findProperty('org.jetbrains.kotlin.native.home') ?: 'dist'
|
||||
dist = (new File(dist)).isAbsolute() ? dist : "${project.getProjectDir()}/$dist"
|
||||
bundleSize = (new File(dist)).directorySize()
|
||||
}
|
||||
currentBenchmarksReportFile = "${buildDir.absolutePath}/${nativeJson}"
|
||||
analyzer = MPPTools.findFile("${analyzerTool}${MPPTools.getNativeProgramExtension()}",
|
||||
def analyzerBinary = MPPTools.findFile("${analyzerTool}${MPPTools.getNativeProgramExtension()}",
|
||||
"${rootBuildDirectory}/${analyzerToolDirectory}")
|
||||
if (analyzerBinary != null) {
|
||||
onlyBranch = project.findProperty('kotlin.register.branch')
|
||||
// Get bundle size.
|
||||
bundleSize = null
|
||||
if (project.findProperty('kotlin.bundleBuild') != null) {
|
||||
def dist = findProperty('org.jetbrains.kotlin.native.home') ?: 'dist'
|
||||
dist = (new File(dist)).isAbsolute() ? dist : "${project.getProjectDir()}/$dist"
|
||||
bundleSize = (new File(dist)).directorySize()
|
||||
}
|
||||
currentBenchmarksReportFile = "${buildDir.absolutePath}/${nativeJson}"
|
||||
analyzer = analyzerBinary
|
||||
}
|
||||
}
|
||||
|
||||
def mergeReports(String fileName) {
|
||||
|
||||
@@ -67,16 +67,16 @@ object LocalCache {
|
||||
fun delete(target: String, builds: Iterable<String>, bintrayUser: String, bintrayPassword: String): Boolean {
|
||||
// Delete from bintray.
|
||||
val buildsDescription = getBuildsInfoFromBintray(target).lines()
|
||||
val initialBuildsNumber = buildsDescription.size
|
||||
buildsDescription.filter {
|
||||
|
||||
val newBuildsDescription = buildsDescription.filter {
|
||||
val buildNumber = it.substringBefore(',')
|
||||
buildNumber !in builds
|
||||
}
|
||||
|
||||
if (buildsDescription.size < initialBuildsNumber) {
|
||||
if (newBuildsDescription.size < buildsDescription.size) {
|
||||
// Upload new version of file.
|
||||
val uploadUrl = "$uploadBintrayUrl/$bintrayPackage/latest/$target/$buildsFileName?publish=1&override=1"
|
||||
sendUploadRequest(uploadUrl, buildsDescription.joinToString("\n"), bintrayUser, bintrayPassword)
|
||||
sendUploadRequest(uploadUrl, newBuildsDescription.joinToString("\n"), bintrayUser, bintrayPassword)
|
||||
|
||||
// Reload values.
|
||||
clean(target)
|
||||
@@ -189,7 +189,7 @@ fun getBuildsInfoFromBintray(target: String) =
|
||||
sendGetRequest("$downloadBintrayUrl/$target/$buildsFileName")
|
||||
|
||||
// Parse and postprocess result of response with build description.
|
||||
fun prepareBuildsResponse(builds: Collection<String>, type: String, buildNumber: String? = null): List<Build> {
|
||||
fun prepareBuildsResponse(builds: Collection<String>, type: String, branch: String, buildNumber: String? = null): List<Build> {
|
||||
val buildsObjects = mutableListOf<Build>()
|
||||
builds.forEach {
|
||||
val tokens = it.split(",").map { it.trim() }
|
||||
@@ -197,7 +197,8 @@ fun prepareBuildsResponse(builds: Collection<String>, type: String, buildNumber:
|
||||
error("Build description $it doesn't contain all necessary information. " +
|
||||
"File with data could be corrupted.")
|
||||
}
|
||||
if (tokens[5] == type || type == "day" || tokens[0] == buildNumber) {
|
||||
if ((tokens[5] == type || type == "day") && (branch == tokens[3] || branch == "all")
|
||||
|| tokens[0] == buildNumber) {
|
||||
buildsObjects.add(Build(tokens[0], tokens[1], tokens[2], tokens[3],
|
||||
tokens[4], tokens[5], tokens[6].toInt(), tokens[7], tokens[8], tokens[9],
|
||||
if (tokens[10] == "-") null else tokens[10]))
|
||||
@@ -233,7 +234,7 @@ fun router() {
|
||||
buildsDescription += "${buildInfo.buildNumber}, ${buildInfo.startTime}, ${buildInfo.finishTime}, " +
|
||||
"${buildInfo.branch}, $commitsDescription, ${register.buildType}, ${register.failuresNumber}, " +
|
||||
"${register.executionTime}, ${register.compileTime}, ${register.codeSize}, " +
|
||||
"${register?.bundleSize ?: "-"}\n"
|
||||
"${register.bundleSize ?: "-"}\n"
|
||||
|
||||
// Upload new version of file.
|
||||
val uploadUrl = "$uploadBintrayUrl/$bintrayPackage/latest/${register.target}/${buildsFileName}?publish=1&override=1"
|
||||
@@ -247,22 +248,22 @@ fun router() {
|
||||
})
|
||||
|
||||
// Get list of builds.
|
||||
router.get("/builds/:target/:type/:id", { request, response ->
|
||||
router.get("/builds/:target/:type/:branch/:id", { request, response ->
|
||||
val builds = LocalCache[request.params.target, request.params.id]
|
||||
response.json(prepareBuildsResponse(builds, request.params.type, request.params.id))
|
||||
response.json(prepareBuildsResponse(builds, request.params.type, request.params.branch, request.params.id))
|
||||
})
|
||||
|
||||
router.get("/builds/:target/:type", { request, response ->
|
||||
router.get("/builds/:target/:type/:branch", { request, response ->
|
||||
val builds = LocalCache[request.params.target]
|
||||
response.json(prepareBuildsResponse(builds, request.params.type))
|
||||
response.json(prepareBuildsResponse(builds, request.params.type, request.params.branch))
|
||||
})
|
||||
|
||||
router.get("/clean", { request, response ->
|
||||
router.get("/clean", { _, response ->
|
||||
LocalCache.clean()
|
||||
response.sendStatus(200)
|
||||
})
|
||||
|
||||
router.get("/fill", { request, response ->
|
||||
router.get("/fill", { _, response ->
|
||||
LocalCache.fill()
|
||||
response.sendStatus(200)
|
||||
})
|
||||
@@ -272,12 +273,13 @@ fun router() {
|
||||
val result = LocalCache.delete(request.params.target, buildsToDelete, request.query.user, request.query.key)
|
||||
if (result) {
|
||||
response.sendStatus(200)
|
||||
} else {
|
||||
response.sendStatus(404)
|
||||
}
|
||||
response.sendStatus(404)
|
||||
})
|
||||
|
||||
// Main page.
|
||||
router.get("/", { request, response ->
|
||||
router.get("/", { _, response ->
|
||||
response.render("index")
|
||||
})
|
||||
|
||||
|
||||
@@ -41,12 +41,12 @@
|
||||
border-color: #d70206;
|
||||
}
|
||||
.ct-legend .ct-series-1:before {
|
||||
background-color: #f05b4f;
|
||||
border-color: #f05b4f;
|
||||
background-color: gold;
|
||||
border-color: gold;
|
||||
}
|
||||
.ct-legend .ct-series-2:before {
|
||||
background-color: #f4c63d;
|
||||
border-color: #f4c63d;
|
||||
background-color: mediumorchid;
|
||||
border-color: mediumorchid;
|
||||
}
|
||||
.ct-legend .ct-series-3:before {
|
||||
background-color: #d17905;
|
||||
@@ -55,4 +55,16 @@
|
||||
.ct-legend .ct-series-4:before {
|
||||
background-color: #453d3f;
|
||||
border-color: #453d3f;
|
||||
}
|
||||
|
||||
.ct-series-b .ct-line,
|
||||
.ct-series-b .ct-point {
|
||||
/* Set the colour of this series line */
|
||||
stroke: gold;
|
||||
}
|
||||
|
||||
.ct-series-c .ct-line,
|
||||
.ct-series-c .ct-point {
|
||||
/* Set the colour of this series line */
|
||||
stroke: mediumorchid;
|
||||
}
|
||||
@@ -50,6 +50,17 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<label class="input-group-text" for="inputGroupBranch">Branch</label>
|
||||
</div>
|
||||
<select class="custom-select" id="inputGroupBranch">
|
||||
<option value="master">master</option>
|
||||
<option value="all">All branches</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
|
||||
@@ -67,14 +67,19 @@ fun <T : Any> separateValues(values: String, valuesContainer: MutableMap<String,
|
||||
}
|
||||
}
|
||||
|
||||
fun getChartData(labels: List<String>, valuesList: Collection<List<*>>): dynamic {
|
||||
fun getChartData(labels: List<String>, valuesList: Collection<List<*>>, className: String? = null): dynamic {
|
||||
val chartData: dynamic = object{}
|
||||
chartData["labels"] = labels.toTypedArray()
|
||||
chartData["series"] = valuesList.map { it.toTypedArray() }.toTypedArray()
|
||||
chartData["series"] = valuesList.map {
|
||||
val series: dynamic = object{}
|
||||
series["data"] = it.toTypedArray()
|
||||
className?.let { series["className"] = className }
|
||||
series
|
||||
}.toTypedArray()
|
||||
return chartData
|
||||
}
|
||||
|
||||
fun getChartOptions(samples: Array<String>, yTitle: String): dynamic {
|
||||
fun getChartOptions(samples: Array<String>, yTitle: String, classNames: Array<String>? = null): dynamic {
|
||||
val chartOptions: dynamic = object{}
|
||||
chartOptions["fullWidth"] = true
|
||||
val paddingObject: dynamic = object{}
|
||||
@@ -88,6 +93,7 @@ fun getChartOptions(samples: Array<String>, yTitle: String): dynamic {
|
||||
chartOptions["axisY"] = axisYObject
|
||||
val legendObject: dynamic = object{}
|
||||
legendObject["legendNames"] = samples
|
||||
classNames?.let { legendObject["classNames"] = classNames }
|
||||
val titleObject: dynamic = object{}
|
||||
val axisYTitle: dynamic = object{}
|
||||
axisYTitle["axisTitle"] = yTitle
|
||||
@@ -103,6 +109,10 @@ fun getChartOptions(samples: Array<String>, yTitle: String): dynamic {
|
||||
return chartOptions
|
||||
}
|
||||
|
||||
fun redirect(url: String) {
|
||||
window.location.href = url
|
||||
}
|
||||
|
||||
fun customizeChart(chart: dynamic, chartContainer: String, jquerySelector: dynamic, builds: List<Build>,
|
||||
parameters: Map<String, String>) {
|
||||
chart.on("draw", { data ->
|
||||
@@ -155,7 +165,7 @@ fun customizeChart(chart: dynamic, chartContainer: String, jquerySelector: dynam
|
||||
element._node.setAttribute("title", information)
|
||||
element._node.setAttribute("data-chart-tooltip", chartContainer)
|
||||
element._node.addEventListener("click", {
|
||||
window.location.replace(linkToDetailedInfo)
|
||||
redirect(linkToDetailedInfo)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -175,7 +185,7 @@ fun main(args: Array<String>) {
|
||||
// Get parameters from request.
|
||||
val url = window.location.href
|
||||
val parametersPart = url.substringAfter("?").split('&')
|
||||
val parameters = mutableMapOf("target" to "Linux", "type" to "dev", "build" to "")
|
||||
val parameters = mutableMapOf("target" to "Linux", "type" to "dev", "build" to "", "branch" to "master")
|
||||
parametersPart.forEach {
|
||||
val parsedParameter = it.split("=", limit = 2)
|
||||
if (parsedParameter.size == 2) {
|
||||
@@ -189,6 +199,7 @@ fun main(args: Array<String>) {
|
||||
append("$serverUrl")
|
||||
append("/${parameters["target"]}")
|
||||
append("/${parameters["type"]}")
|
||||
append("/${parameters["branch"]}")
|
||||
append("/${parameters["build"]}")
|
||||
}
|
||||
val response = sendGetRequest(buildsUrl)
|
||||
@@ -205,23 +216,32 @@ fun main(args: Array<String>) {
|
||||
// Change inputs values connected with parameters and add events listeners.
|
||||
document.querySelector("#inputGroupTarget [value=\"${parameters["target"]}\"]")?.setAttribute("selected", "true")
|
||||
document.querySelector("#inputGroupBuildType [value=\"${parameters["type"]}\"]")?.setAttribute("selected", "true")
|
||||
document.querySelector("#inputGroupBranch [value=\"${parameters["branch"]}\"]")?.setAttribute("selected", "true")
|
||||
(document.getElementById("highligted_build") as HTMLInputElement).value = parameters["build"]!!
|
||||
|
||||
// Add onChange events for fields.
|
||||
js("$('#inputGroupTarget')").change({
|
||||
val newValue = js("$(this).val()")
|
||||
if (newValue != parameters["target"]) {
|
||||
val newLink = "http://${window.location.host}/?target=$newValue&type=${parameters["type"]}" +
|
||||
val newLink = "http://${window.location.host}/?target=$newValue&type=${parameters["type"]}&branch=${parameters["branch"]}" +
|
||||
"${if (parameters["build"]!!.isEmpty()) "" else "&build=${parameters["build"]}"}"
|
||||
window.location.replace(newLink)
|
||||
window.location.href = newLink
|
||||
}
|
||||
})
|
||||
js("$('#inputGroupBuildType')").change({
|
||||
val newValue = js("$(this).val()")
|
||||
if (newValue != parameters["type"]) {
|
||||
val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=$newValue" +
|
||||
val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=$newValue&branch=${parameters["branch"]}" +
|
||||
"${if (parameters["build"]!!.isEmpty()) "" else "&build=${parameters["build"]}"}"
|
||||
window.location.replace(newLink)
|
||||
window.location.href = newLink
|
||||
}
|
||||
})
|
||||
js("$('#inputGroupBranch')").change({
|
||||
val newValue = js("$(this).val()")
|
||||
if (newValue != parameters["branch"]) {
|
||||
val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=${parameters["type"]}&branch=$newValue" +
|
||||
"${if (parameters["build"]!!.isEmpty()) "" else "&build=${parameters["build"]}"}"
|
||||
window.location.href = newLink
|
||||
}
|
||||
})
|
||||
|
||||
@@ -231,7 +251,7 @@ fun main(args: Array<String>) {
|
||||
if (suggestion.value != parameters["build"]) {
|
||||
val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=${parameters["type"]}" +
|
||||
"${if (suggestion.value.isEmpty()) "" else "&build=${suggestion.value}"}"
|
||||
window.location.replace(newLink)
|
||||
window.location.href = newLink
|
||||
}
|
||||
}
|
||||
js("$( \"#highligted_build\" )").autocomplete(autocompleteParameters)
|
||||
@@ -240,7 +260,7 @@ fun main(args: Array<String>) {
|
||||
if (newValue.isEmpty() || newValue in builds.map {it.buildNumber}) {
|
||||
val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=${parameters["type"]}" +
|
||||
"${if (newValue.isEmpty()) "" else "&build=$newValue"}"
|
||||
window.location.replace(newLink)
|
||||
window.location.href = newLink
|
||||
}
|
||||
})
|
||||
|
||||
@@ -260,20 +280,22 @@ fun main(args: Array<String>) {
|
||||
labels.add(it.buildNumber)
|
||||
}
|
||||
separateValues(it.executionTime, executionTime) { value -> value.toDouble() }
|
||||
separateValues(it.compileTime, compileTime) { value -> value.toDouble() }
|
||||
separateValues(it.compileTime, compileTime) { value -> value.toDouble() / 1000 }
|
||||
separateValues(it.codeSize, codeSize) { value -> value.toDouble() / 1024.0 }
|
||||
bundleSize.add(it.bundleSize?.toInt()?. let { it / 1024 / 1024 })
|
||||
}
|
||||
|
||||
val sizeClassName = "ct-series-c"
|
||||
|
||||
// Draw charts.
|
||||
val execChart = Chartist.Line("#exec_chart", getChartData(labels, executionTime.values),
|
||||
getChartOptions(executionTime.keys.toTypedArray(), "Time, microseconds"))
|
||||
val compileChart = Chartist.Line("#compile_chart", getChartData(labels, compileTime.values),
|
||||
getChartOptions(compileTime.keys.toTypedArray(), "Time, microseconds"))
|
||||
val codeSizeChart = Chartist.Line("#codesize_chart", getChartData(labels, codeSize.values),
|
||||
getChartOptions(codeSize.keys.toTypedArray(), "Size, KB"))
|
||||
val bundleSizeChart = Chartist.Line("#bundlesize_chart", getChartData(labels, listOf(bundleSize)),
|
||||
getChartOptions(arrayOf("Bundle size"), "Size, MB"))
|
||||
getChartOptions(compileTime.keys.toTypedArray(), "Time, milliseconds"))
|
||||
val codeSizeChart = Chartist.Line("#codesize_chart", getChartData(labels, codeSize.values, sizeClassName),
|
||||
getChartOptions(codeSize.keys.toTypedArray(), "Size, KB", arrayOf("ct-series-2")))
|
||||
val bundleSizeChart = Chartist.Line("#bundlesize_chart", getChartData(labels, listOf(bundleSize), sizeClassName),
|
||||
getChartOptions(arrayOf("Bundle size"), "Size, MB", arrayOf("ct-series-2")))
|
||||
|
||||
// Tooltips and higlights.
|
||||
customizeChart(execChart, "exec_chart", js("$(\"#exec_chart\")"), builds, parameters)
|
||||
|
||||
Reference in New Issue
Block a user