1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
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 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
}
}
|