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  }