flamingo.me/flamingo-commerce/v3@v3.11.0/checkout/infrastructure/locker/memory.go (about)

     1  package locker
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  	"time"
     7  
     8  	"flamingo.me/flamingo-commerce/v3/checkout/application/placeorder"
     9  )
    10  
    11  type (
    12  	// Memory TryLocker for non clustered applications
    13  	Memory struct {
    14  		mainLocker sync.Locker
    15  		locks      map[string]struct{}
    16  	}
    17  )
    18  
    19  var _ placeorder.TryLocker = &Memory{}
    20  
    21  // NewMemory creates a new memory based lock
    22  func NewMemory() *Memory {
    23  	return &Memory{mainLocker: &sync.Mutex{}, locks: make(map[string]struct{})}
    24  }
    25  
    26  func (m *Memory) locked(id string) (ok bool) { _, ok = m.locks[id]; return }
    27  
    28  // TryLock unblocking implementation see https://github.com/LK4D4/trylock/blob/master/trylock.go
    29  func (m *Memory) TryLock(_ context.Context, key string, _ time.Duration) (placeorder.Unlock, error) {
    30  	m.mainLocker.Lock()
    31  	defer m.mainLocker.Unlock()
    32  	if m.locked(key) {
    33  		return nil, placeorder.ErrLockTaken
    34  	}
    35  	m.locks[key] = struct{}{}
    36  	return func() error {
    37  		m.mainLocker.Lock()
    38  		defer m.mainLocker.Unlock()
    39  		delete(m.locks, key)
    40  		return nil
    41  	}, nil
    42  }