mirror of
https://github.com/gitpod-io/gitpod.git
synced 2025-12-08 17:36:30 +00:00
100 lines
2.2 KiB
Go
100 lines
2.2 KiB
Go
// Copyright (c) 2022 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 (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/gitpod-io/gitpod/common-go/log"
|
|
"github.com/gitpod-io/gitpod/loadgen/pkg/loadgen"
|
|
"github.com/gitpod-io/gitpod/ws-manager/api"
|
|
)
|
|
|
|
type SuccessObserver struct {
|
|
workspaces map[string]*workspaceSuccess
|
|
m sync.Mutex
|
|
successRate float32
|
|
}
|
|
|
|
type workspaceSuccess struct {
|
|
Phase api.WorkspacePhase
|
|
Failed bool
|
|
}
|
|
|
|
func NewSuccessObserver(successRate float32) *SuccessObserver {
|
|
return &SuccessObserver{
|
|
workspaces: make(map[string]*workspaceSuccess),
|
|
successRate: successRate,
|
|
}
|
|
}
|
|
|
|
func (o *SuccessObserver) Observe() chan<- *loadgen.SessionEvent {
|
|
res := make(chan *loadgen.SessionEvent, defaultCapacity)
|
|
|
|
go func() {
|
|
for evt := range res {
|
|
switch evt.Kind {
|
|
case loadgen.SessionWorkspaceStart:
|
|
o.m.Lock()
|
|
o.workspaces[evt.WorkspaceStart.Spec.Id] = &workspaceSuccess{}
|
|
o.m.Unlock()
|
|
|
|
case loadgen.SessionWorkspaceUpdate:
|
|
{
|
|
up := evt.WorkspaceUpdate.Update
|
|
o.m.Lock()
|
|
ws, ok := o.workspaces[up.InstanceID]
|
|
o.m.Unlock()
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
ws.Phase = up.Phase
|
|
ws.Failed = up.Failed
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
return res
|
|
}
|
|
|
|
func (o *SuccessObserver) Wait(ctx context.Context, expected int) error {
|
|
ticker := time.NewTicker(2 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
o.m.Lock()
|
|
running := 0
|
|
for _, ws := range o.workspaces {
|
|
if ws.Phase == api.WorkspacePhase_RUNNING {
|
|
running += 1
|
|
}
|
|
}
|
|
|
|
if float32(running) >= float32(len(o.workspaces))*o.successRate {
|
|
return nil
|
|
}
|
|
|
|
o.m.Unlock()
|
|
case <-ctx.Done():
|
|
o.m.Lock()
|
|
log.Warnf("workspaces did not get ready in time. Expected %v workspaces, did see %v", expected, len(o.workspaces))
|
|
for id, ws := range o.workspaces {
|
|
if ws.Phase != api.WorkspacePhase_RUNNING {
|
|
log.Warnf("workspace %s is in phase %v", id, ws.Phase)
|
|
}
|
|
}
|
|
o.m.Unlock()
|
|
return fmt.Errorf("timeout waiting for workspace to get ready")
|
|
}
|
|
}
|
|
}
|