mirror of
https://github.com/gitpod-io/gitpod.git
synced 2025-12-08 17:36:30 +00:00
87 lines
2.1 KiB
Go
87 lines
2.1 KiB
Go
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.
|
|
// Licensed under the GNU Affero General Public License (AGPL).
|
|
// See License.AGPL.txt in the project root for license information.
|
|
|
|
package observer
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/gitpod-io/gitpod/loadgen/pkg/loadgen"
|
|
"github.com/gitpod-io/gitpod/ws-manager/api"
|
|
)
|
|
|
|
const (
|
|
defaultCapacity = 200
|
|
)
|
|
|
|
// Stats is stats across a whole session
|
|
type Stats struct {
|
|
Total int `json:"total"`
|
|
Failed int `json:"failed"`
|
|
Running int `json:"running"`
|
|
Samples []StatsSample `json:"samples"`
|
|
}
|
|
|
|
// StatsSample is a single workspace sample
|
|
type StatsSample struct {
|
|
InstanceID string
|
|
Start, Running time.Time
|
|
Phase api.WorkspacePhase
|
|
Failed bool
|
|
StartDuration time.Duration
|
|
}
|
|
|
|
// NewStatsObserver produces a stats collecting observer
|
|
func NewStatsObserver(cb func(*Stats)) chan<- *loadgen.SessionEvent {
|
|
res := make(chan *loadgen.SessionEvent, defaultCapacity)
|
|
|
|
publishStats := func(status map[string]*StatsSample) {
|
|
var s Stats
|
|
s.Samples = make([]StatsSample, 0, len(status))
|
|
for _, ws := range status {
|
|
s.Total++
|
|
if ws.Failed {
|
|
s.Failed++
|
|
}
|
|
if ws.Phase == api.WorkspacePhase_RUNNING {
|
|
s.Running++
|
|
}
|
|
s.Samples = append(s.Samples, *ws)
|
|
}
|
|
|
|
cb(&s)
|
|
}
|
|
|
|
go func() {
|
|
status := make(map[string]*StatsSample)
|
|
for evt := range res {
|
|
switch evt.Kind {
|
|
case loadgen.SessionStart:
|
|
status = make(map[string]*StatsSample)
|
|
case loadgen.SessionWorkspaceStart:
|
|
status[evt.WorkspaceStart.Spec.Id] = &StatsSample{
|
|
InstanceID: evt.WorkspaceStart.Spec.Id,
|
|
Start: evt.WorkspaceStart.Time,
|
|
Failed: false,
|
|
Phase: api.WorkspacePhase_UNKNOWN,
|
|
StartDuration: evt.WorkspaceStart.CallDuration,
|
|
}
|
|
case loadgen.SessionWorkspaceUpdate:
|
|
up := evt.WorkspaceUpdate.Update
|
|
ws, ok := status[up.InstanceID]
|
|
if !ok {
|
|
continue
|
|
}
|
|
ws.Phase = up.Phase
|
|
ws.Failed = up.Failed
|
|
ws.Running = evt.WorkspaceUpdate.Time
|
|
publishStats(status)
|
|
case loadgen.SessionDone:
|
|
publishStats(status)
|
|
}
|
|
}
|
|
}()
|
|
return res
|
|
}
|