package locker import ( "context" "github.com/sour-is/ev/internal/lg" ) type Locked[T any] struct { state chan *T } // New creates a new locker for the given value. func New[T any](initial *T) *Locked[T] { s := &Locked[T]{} s.state = make(chan *T, 1) s.state <- initial return s } // Modify will call the function with the locked value func (s *Locked[T]) Modify(ctx context.Context, fn func(*T) error) error { _, span := lg.Span(ctx) defer span.End() if ctx.Err() != nil { return ctx.Err() } select { case state := <-s.state: defer func() { s.state <- state }() return fn(state) case <-ctx.Done(): return ctx.Err() } } // Copy will return a shallow copy of the locked object. func (s *Locked[T]) Copy(ctx context.Context) (T, error) { var t T err := s.Modify(ctx, func(c *T) error { if c != nil { t = *c } return nil }) return t, err }