github.com/trawler/terraform@v0.10.8-0.20171106022149-4b1c7a1d9b48/terraform/util.go (about)

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