github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/lock/process.go (about) 1 package lock 2 3 import ( 4 "context" 5 "time" 6 7 "golang.org/x/sync/singleflight" 8 ) 9 10 type processLocker struct { 11 locker *singleflight.Group 12 } 13 14 func (m *processLocker) Do(ctx context.Context, name string, duration time.Duration, fn func(ctx context.Context) error) error { 15 ctx, _ = context.WithTimeout(ctx, duration) 16 resCh := m.locker.DoChan(name, func() (i interface{}, err error) { 17 err = fn(ctx) 18 return 19 }) 20 defer m.locker.Forget(name) 21 22 select { 23 case <-ctx.Done(): 24 return ctx.Err() 25 case res := <-resCh: 26 return res.Err 27 } 28 } 29 30 func NewProcessLocker() Locker { 31 return &processLocker{locker: &singleflight.Group{}} 32 }