Files
buildkit/session/group.go
Tonis Tiigi e05a89e0b8 improve stacks of cancels from defers
In this case the current stack trace points to the line
where the context was created. Instead the stack should be
captured when the defer is running so the return path to
the defer call is also part of the stack.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2024-11-19 18:40:00 -08:00

90 lines
1.5 KiB
Go

package session
import (
"context"
"time"
"github.com/pkg/errors"
)
type Group interface {
SessionIterator() Iterator
}
type Iterator interface {
NextSession() string
}
func NewGroup(ids ...string) Group {
return &group{ids: ids}
}
type group struct {
ids []string
}
func (g *group) SessionIterator() Iterator {
return &group{ids: g.ids}
}
func (g *group) NextSession() string {
if len(g.ids) == 0 {
return ""
}
v := g.ids[0]
g.ids = g.ids[1:]
return v
}
func AllSessionIDs(g Group) (out []string) {
if g == nil {
return nil
}
it := g.SessionIterator()
if it == nil {
return nil
}
for {
v := it.NextSession()
if v == "" {
return
}
out = append(out, v)
}
}
func (sm *Manager) Any(ctx context.Context, g Group, f func(context.Context, string, Caller) error) error {
if g == nil {
return nil
}
iter := g.SessionIterator()
if iter == nil {
return nil
}
var lastErr error
for {
id := iter.NextSession()
if id == "" {
if lastErr != nil {
return lastErr
}
return errors.Errorf("no active sessions")
}
timeoutCtx, cancel := context.WithCancelCause(ctx)
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 5*time.Second, errors.WithStack(context.DeadlineExceeded))
defer func() { cancel(errors.WithStack(context.Canceled)) }()
c, err := sm.Get(timeoutCtx, id, false)
if err != nil {
lastErr = err
continue
}
if err := f(ctx, id, c); err != nil {
lastErr = err
continue
}
return nil
}
}