github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/internal/terraform/util.go (about)

     1  package terraform
     2  
     3  import (
     4  	"sort"
     5  )
     6  
     7  // Semaphore is a wrapper around a channel to provide
     8  // utility methods to clarify that we are treating the
     9  // channel as a semaphore
    10  type Semaphore chan struct{}
    11  
    12  // NewSemaphore creates a semaphore that allows up
    13  // to a given limit of simultaneous acquisitions
    14  func NewSemaphore(n int) Semaphore {
    15  	if n <= 0 {
    16  		panic("semaphore with limit <=0")
    17  	}
    18  	ch := make(chan struct{}, n)
    19  	return Semaphore(ch)
    20  }
    21  
    22  // Acquire is used to acquire an available slot.
    23  // Blocks until available.
    24  func (s Semaphore) Acquire() {
    25  	s <- struct{}{}
    26  }
    27  
    28  // TryAcquire is used to do a non-blocking acquire.
    29  // Returns a bool indicating success
    30  func (s Semaphore) TryAcquire() bool {
    31  	select {
    32  	case s <- struct{}{}:
    33  		return true
    34  	default:
    35  		return false
    36  	}
    37  }
    38  
    39  // Release is used to return a slot. Acquire must
    40  // be called as a pre-condition.
    41  func (s Semaphore) Release() {
    42  	select {
    43  	case <-s:
    44  	default:
    45  		panic("release without an acquire")
    46  	}
    47  }
    48  
    49  // strSliceContains checks if a given string is contained in a slice
    50  // When anybody asks why Go needs generics, here you go.
    51  func strSliceContains(haystack []string, needle string) bool {
    52  	for _, s := range haystack {
    53  		if s == needle {
    54  			return true
    55  		}
    56  	}
    57  	return false
    58  }
    59  
    60  // deduplicate a slice of strings
    61  func uniqueStrings(s []string) []string {
    62  	if len(s) < 2 {
    63  		return s
    64  	}
    65  
    66  	sort.Strings(s)
    67  	result := make([]string, 1, len(s))
    68  	result[0] = s[0]
    69  	for i := 1; i < len(s); i++ {
    70  		if s[i] != result[len(result)-1] {
    71  			result = append(result, s[i])
    72  		}
    73  	}
    74  	return result
    75  }