github.com/chanzuckerberg/terraform@v0.11.12-beta1/helper/mutexkv/mutexkv.go (about)

     1  package mutexkv
     2  
     3  import (
     4  	"log"
     5  	"sync"
     6  )
     7  
     8  // MutexKV is a simple key/value store for arbitrary mutexes. It can be used to
     9  // serialize changes across arbitrary collaborators that share knowledge of the
    10  // keys they must serialize on.
    11  //
    12  // The initial use case is to let aws_security_group_rule resources serialize
    13  // their access to individual security groups based on SG ID.
    14  type MutexKV struct {
    15  	lock  sync.Mutex
    16  	store map[string]*sync.Mutex
    17  }
    18  
    19  // Locks the mutex for the given key. Caller is responsible for calling Unlock
    20  // for the same key
    21  func (m *MutexKV) Lock(key string) {
    22  	log.Printf("[DEBUG] Locking %q", key)
    23  	m.get(key).Lock()
    24  	log.Printf("[DEBUG] Locked %q", key)
    25  }
    26  
    27  // Unlock the mutex for the given key. Caller must have called Lock for the same key first
    28  func (m *MutexKV) Unlock(key string) {
    29  	log.Printf("[DEBUG] Unlocking %q", key)
    30  	m.get(key).Unlock()
    31  	log.Printf("[DEBUG] Unlocked %q", key)
    32  }
    33  
    34  // Returns a mutex for the given key, no guarantee of its lock status
    35  func (m *MutexKV) get(key string) *sync.Mutex {
    36  	m.lock.Lock()
    37  	defer m.lock.Unlock()
    38  	mutex, ok := m.store[key]
    39  	if !ok {
    40  		mutex = &sync.Mutex{}
    41  		m.store[key] = mutex
    42  	}
    43  	return mutex
    44  }
    45  
    46  // Returns a properly initalized MutexKV
    47  func NewMutexKV() *MutexKV {
    48  	return &MutexKV{
    49  		store: make(map[string]*sync.Mutex),
    50  	}
    51  }