Add running/total job count to home

This commit is contained in:
Lou Knauer 2022-02-16 12:29:54 +01:00
parent 19b2b6c2a9
commit 62e776ef7d
3 changed files with 105 additions and 11 deletions

View File

@ -96,6 +96,47 @@ func (r *JobRepository) Stop(
return
}
// CountJobs returns the number of jobs for the specified user (if a non-admin user is found in that context) and state.
// The counts are grouped by cluster.
func (r *JobRepository) CountJobs(ctx context.Context, state *schema.JobState) (map[string]int, error) {
// q := sq.Select("count(*)").From("job")
// if cluster != nil {
// q = q.Where("job.cluster = ?", cluster)
// }
// if state != nil {
// q = q.Where("job.job_state = ?", string(*state))
// }
// err = q.RunWith(r.DB).QueryRow().Scan(&count)
// return
q := sq.Select("job.cluster, count(*)").From("job").GroupBy("job.cluster")
if state != nil {
q = q.Where("job.job_state = ?", string(*state))
}
if user := auth.GetUser(ctx); user != nil && !user.HasRole(auth.RoleAdmin) {
q = q.Where("job.user = ?", user.Username)
}
counts := map[string]int{}
rows, err := q.RunWith(r.DB).Query()
if err != nil {
return nil, err
}
for rows.Next() {
var cluster string
var count int
if err := rows.Scan(&cluster, &count); err != nil {
return nil, err
}
counts[cluster] = count
}
return counts, nil
}
// func (r *JobRepository) Query(
// filters []*model.JobFilter,
// page *model.PageRequest,

View File

@ -28,6 +28,7 @@ import (
"github.com/ClusterCockpit/cc-backend/log"
"github.com/ClusterCockpit/cc-backend/metricdata"
"github.com/ClusterCockpit/cc-backend/repository"
"github.com/ClusterCockpit/cc-backend/schema"
"github.com/ClusterCockpit/cc-backend/templates"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
@ -121,6 +122,38 @@ var programConfig ProgramConfig = ProgramConfig{
},
}
func setupHomeRoute(i InfoType, r *http.Request) InfoType {
type cluster struct {
Name string
RunningJobs int
TotalJobs int
}
state := schema.JobStateRunning
runningJobs, err := jobRepo.CountJobs(r.Context(), &state)
if err != nil {
log.Errorf("failed to count jobs: %s", err.Error())
runningJobs = map[string]int{}
}
totalJobs, err := jobRepo.CountJobs(r.Context(), nil)
if err != nil {
log.Errorf("failed to count jobs: %s", err.Error())
totalJobs = map[string]int{}
}
clusters := make([]cluster, 0)
for _, c := range config.Clusters {
clusters = append(clusters, cluster{
Name: c.Name,
RunningJobs: runningJobs[c.Name],
TotalJobs: totalJobs[c.Name],
})
}
i["clusters"] = clusters
return i
}
func setupJobRoute(i InfoType, r *http.Request) InfoType {
i["id"] = mux.Vars(r)["id"]
return i
@ -189,7 +222,7 @@ func setupTaglistRoute(i InfoType, r *http.Request) InfoType {
}
var routes []Route = []Route{
{"/", "home.tmpl", "ClusterCockpit", false, func(i InfoType, r *http.Request) InfoType { i["clusters"] = config.Clusters; return i }},
{"/", "home.tmpl", "ClusterCockpit", false, setupHomeRoute},
{"/monitoring/jobs/", "monitoring/jobs.tmpl", "Jobs - ClusterCockpit", true, func(i InfoType, r *http.Request) InfoType { return i }},
{"/monitoring/job/{id:[0-9]+}", "monitoring/job.tmpl", "Job <ID> - ClusterCockpit", false, setupJobRoute},
{"/monitoring/users/", "monitoring/list.tmpl", "Users - ClusterCockpit", true, func(i InfoType, r *http.Request) InfoType { i["listType"] = "USER"; return i }},
@ -454,7 +487,10 @@ func main() {
handlers.AllowedMethods([]string{"GET", "POST", "HEAD", "OPTIONS"}),
handlers.AllowedOrigins([]string{"*"})))
handler := handlers.CustomLoggingHandler(log.InfoWriter, r, func(w io.Writer, params handlers.LogFormatterParams) {
log.Finfof(w, "%s %s (Response: %d, Size: %d)", params.Request.Method, params.URL.RequestURI(), params.StatusCode, params.Size)
log.Finfof(w, "%s %s (status: %d, size: %d, duration: %dms)",
params.Request.Method, params.URL.RequestURI(),
params.StatusCode, params.Size,
time.Since(params.TimeStamp).Milliseconds())
})
var wg sync.WaitGroup

View File

@ -6,19 +6,36 @@
<thead>
<tr>
<th>Name</th>
<th>Running Jobs</th>
<th>Total Jobs</th>
<th>Jobs</th>
<th>System View</th>
<th>Analysis View</th>
{{if .User.IsAdmin}}
<th>System View</th>
<th>Analysis View</th>
{{end}}
</tr>
</thead>
<tbody>
{{range .Infos.clusters}}
<tr>
<td>{{.Name}}</td>
<td><a href="/monitoring/jobs/?cluster={{.Name}}">Jobs</a></td>
<td><a href="/monitoring/systems/{{.Name}}">System View</a></td>
<td><a href="/monitoring/analysis/{{.Name}}">Analysis View</a></td>
</tr>
{{if .User.IsAdmin}}
{{range .Infos.clusters}}
<tr>
<td>{{.Name}}</td>
<td>{{.RunningJobs}}</td>
<td>{{.TotalJobs}}</td>
<td><a href="/monitoring/jobs/?cluster={{.Name}}">Jobs</a></td>
<td><a href="/monitoring/systems/{{.Name}}">System View</a></td>
<td><a href="/monitoring/analysis/{{.Name}}">Analysis View</a></td>
</tr>
{{end}}
{{else}}
{{range .Infos.clusters}}
<tr>
<td>{{.Name}}</td>
<td>{{.RunningJobs}}</td>
<td>{{.TotalJobs}}</td>
<td><a href="/monitoring/jobs/?cluster={{.Name}}">Jobs</a></td>
</tr>
{{end}}
{{end}}
</tbody>
</table>