2022-12-08 13:05:19 -03:00

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
}