package memory import ( "context" "time" "forge.cadoles.com/cadoles/bouncer/internal/lock" "github.com/pkg/errors" ) var ( ErrTimeout = errors.New("timeout") ) type Locker struct { lock chan struct{} } // WithLock implements lock.Locker. func (l *Locker) WithLock(ctx context.Context, key string, timeout time.Duration, fn func(ctx context.Context) error) error { select { case l.lock <- struct{}{}: defer func() { <-l.lock }() if err := fn(ctx); err != nil { return errors.WithStack(err) } case <-ctx.Done(): return errors.WithStack(ctx.Err()) case <-time.After(timeout): return errors.WithStack(ErrTimeout) } return nil } func NewLocker() *Locker { return &Locker{ lock: make(chan struct{}, 1), } } var _ lock.Locker = &Locker{}