зеркало из https://github.com/golang/build.git
cmd/coordinator: add more information to queues UI
This change adds the branch and how long an item has been in the queue. Change-Id: I05e7c466119c04c68ed4ef3882f23c5fb1ce0c3d Reviewed-on: https://go-review.googlesource.com/c/build/+/420754 Run-TryBot: Jenny Rakoczy <jenny@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Jenny Rakoczy <jenny@golang.org>
This commit is contained in:
Родитель
b196ddadc4
Коммит
fdd64c3913
|
@ -284,6 +284,7 @@ func (st *buildStatus) onceInitHelpersFunc() {
|
|||
IsTry: st.isTry(),
|
||||
CommitTime: st.commitTime(),
|
||||
Branch: st.branch(),
|
||||
Repo: st.RepoOrGo(),
|
||||
User: st.AuthorEmail,
|
||||
}
|
||||
st.helpers = getBuildlets(st.ctx, st.conf.NumTestHelpers(st.isTry()), schedTmpl, st)
|
||||
|
@ -379,6 +380,7 @@ func (st *buildStatus) getBuildlet() (buildlet.Client, error) {
|
|||
IsTry: st.trySet != nil,
|
||||
BuilderRev: st.BuilderRev,
|
||||
CommitTime: st.commitTime(),
|
||||
Repo: st.RepoOrGo(),
|
||||
Branch: st.branch(),
|
||||
User: st.AuthorEmail,
|
||||
}
|
||||
|
@ -701,6 +703,7 @@ func (st *buildStatus) crossCompileMakeAndSnapshot(config *dashboard.CrossCompil
|
|||
IsTry: st.trySet != nil,
|
||||
BuilderRev: st.BuilderRev,
|
||||
CommitTime: st.commitTime(),
|
||||
Repo: st.RepoOrGo(),
|
||||
Branch: st.branch(),
|
||||
User: st.AuthorEmail,
|
||||
})
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"golang.org/x/build/internal/coordinator/pool"
|
||||
"golang.org/x/build/internal/coordinator/pool/queue"
|
||||
|
@ -21,7 +22,10 @@ import (
|
|||
//go:embed templates/queues.html
|
||||
var queuesTemplateStr string
|
||||
|
||||
var queuesTemplate = template.Must(baseTmpl.New("queues.html").Parse(queuesTemplateStr))
|
||||
var queuesTemplate = template.Must(baseTmpl.New("queues.html").Funcs(map[string]interface{}{
|
||||
"timeSince": timeSince,
|
||||
"humanDuration": humanDuration,
|
||||
}).Parse(queuesTemplateStr))
|
||||
|
||||
type QueuesResponse struct {
|
||||
Queues map[string]*queue.QuotaStats
|
||||
|
@ -41,3 +45,94 @@ func handleQueues(w http.ResponseWriter, _ *http.Request) {
|
|||
log.Printf("handleQueues: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func timeSince(t time.Time) time.Duration {
|
||||
return time.Since(t)
|
||||
}
|
||||
|
||||
// humanDuration is largely time.Duration's formatting, but modified
|
||||
// to imprecisely format days, even though days may vary in length
|
||||
// due to daylight savings time. Sub-second durations are
|
||||
// represented as 0s.
|
||||
func humanDuration(d time.Duration) string {
|
||||
var buf [32]byte
|
||||
w := len(buf)
|
||||
|
||||
u := uint64(d)
|
||||
neg := d < 0
|
||||
if neg {
|
||||
u = -u
|
||||
}
|
||||
w--
|
||||
buf[w] = 's'
|
||||
|
||||
_, u = fmtFrac(buf[:w], u, 9)
|
||||
|
||||
// u is now integer seconds
|
||||
w = fmtInt(buf[:w], u%60)
|
||||
u /= 60
|
||||
|
||||
// u is now integer minutes
|
||||
if u > 0 {
|
||||
w--
|
||||
buf[w] = 'm'
|
||||
w = fmtInt(buf[:w], u%60)
|
||||
u /= 60
|
||||
|
||||
// u is now integer hours
|
||||
if u > 0 {
|
||||
w--
|
||||
buf[w] = 'h'
|
||||
w = fmtInt(buf[:w], u%24)
|
||||
u /= 24
|
||||
if u > 0 {
|
||||
w--
|
||||
buf[w] = 'd'
|
||||
w = fmtInt(buf[:w], u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if neg {
|
||||
w--
|
||||
buf[w] = '-'
|
||||
}
|
||||
return string(buf[w:])
|
||||
}
|
||||
|
||||
// fmtFrac is identical to fmtFrac in the time package.
|
||||
func fmtFrac(buf []byte, v uint64, prec int) (nw int, nv uint64) {
|
||||
// Omit trailing zeros up to and including decimal point.
|
||||
w := len(buf)
|
||||
print := false
|
||||
for i := 0; i < prec; i++ {
|
||||
digit := v % 10
|
||||
print = print || digit != 0
|
||||
if print {
|
||||
w--
|
||||
buf[w] = byte(digit) + '0'
|
||||
}
|
||||
v /= 10
|
||||
}
|
||||
if print {
|
||||
w--
|
||||
buf[w] = '.'
|
||||
}
|
||||
return w, v
|
||||
}
|
||||
|
||||
// fmtFrac is identical to fmtInt in the time package.
|
||||
func fmtInt(buf []byte, v uint64) int {
|
||||
w := len(buf)
|
||||
if v == 0 {
|
||||
w--
|
||||
buf[w] = '0'
|
||||
} else {
|
||||
for v > 0 {
|
||||
w--
|
||||
buf[w] = byte(v%10) + '0'
|
||||
v /= 10
|
||||
}
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.16 && (linux || darwin)
|
||||
// +build go1.16
|
||||
// +build linux darwin
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestHumanDuration(t *testing.T) {
|
||||
cases := []struct {
|
||||
desc string
|
||||
duration string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
desc: "format days",
|
||||
duration: "99h2m1s",
|
||||
want: "4d3h2m1s",
|
||||
},
|
||||
{
|
||||
desc: "handle tiny durations",
|
||||
duration: "1ns",
|
||||
want: "0s",
|
||||
},
|
||||
{
|
||||
desc: "handle seconds",
|
||||
duration: "3s",
|
||||
want: "3s",
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.duration, func(t *testing.T) {
|
||||
d, err := time.ParseDuration(c.duration)
|
||||
if err != nil {
|
||||
t.Fatalf("time.ParseDuration(%q) = %q, %q, wanted no error", c.duration, d, err)
|
||||
}
|
||||
if got := humanDuration(d); got != c.want {
|
||||
t.Errorf("humanDuration(%v) = %q, wanted %q", d, got, c.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -197,5 +197,5 @@ table.Build tbody tr.commit:hover {
|
|||
border: 0.0625rem solid #d6d6d6;
|
||||
border-radius: 0.1875rem;
|
||||
margin: 1rem;
|
||||
width: 31rem;
|
||||
width: 44rem;
|
||||
}
|
||||
|
|
|
@ -25,9 +25,11 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th class="QueueStats-queueTableHeader">Name</th>
|
||||
<th class="QueueStats-queueTableHeader">Branch</th>
|
||||
<th class="QueueStats-queueTableHeader">Cost</th>
|
||||
<th class="QueueStats-queueTableHeader">Type/Priority</th>
|
||||
<th class="QueueStats-queueTableHeader">Priority</th>
|
||||
<th class="QueueStats-queueTableHeader">User</th>
|
||||
<th class="QueueStats-queueTableHeader">Waiting</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -35,7 +37,10 @@
|
|||
<tr class="QueueStats-queueTableRow">
|
||||
{{$build := $item.Build}}
|
||||
<td class="QueueStats-queueTableColumn">
|
||||
{{$item.Build.HostType}}
|
||||
{{$item.Build.Name}}
|
||||
</td>
|
||||
<td class="QueueStats-queueTableColumn">
|
||||
{{printf "%s/%s" $item.Build.Repo $item.Build.Branch}}
|
||||
</td>
|
||||
<td class="QueueStats-queueTableColumn">
|
||||
{{$item.Cost}}
|
||||
|
@ -50,18 +55,18 @@
|
|||
{{else}}
|
||||
Post-submit
|
||||
{{end}}
|
||||
/
|
||||
{{$build.Priority}}
|
||||
({{$build.Priority}})
|
||||
</td>
|
||||
<td class="QueueStats-queueTableColumn">
|
||||
{{$build.User}}
|
||||
</td>
|
||||
<td class="QueueStats-queueTableColumn">
|
||||
{{humanDuration (timeSince $build.RequestTime)}}
|
||||
</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr class="QueueStats-queueTableRow">
|
||||
<td class="QueueStats-queueTableColumn" colspan="4">
|
||||
Queue empty.
|
||||
</td>
|
||||
<td class="QueueStats-queueTableColumn" colspan="6">Queue empty.</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
|
|
|
@ -32,6 +32,7 @@ type SchedItem struct {
|
|||
IsGomote bool
|
||||
IsTry bool
|
||||
IsHelper bool
|
||||
Repo string
|
||||
Branch string
|
||||
|
||||
// CommitTime is the latest commit date of the relevant repos
|
||||
|
|
Загрузка…
Ссылка в новой задаче