mirror of
https://github.com/moby/buildkit.git
synced 2026-08-05 15:20:22 +00:00
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>
90 lines
1.5 KiB
Go
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
|
|
}
|
|
}
|