github.com/federicobaldo/terraform@v0.6.15-0.20160323222747-b20f680cbf05/terraform/util.go (about) 1 package terraform 2 3 import ( 4 "strings" 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 // resourceProvider returns the provider name for the given type. 50 func resourceProvider(t, alias string) string { 51 if alias != "" { 52 return alias 53 } 54 55 idx := strings.IndexRune(t, '_') 56 if idx == -1 { 57 return "" 58 } 59 60 return t[:idx] 61 } 62 63 // strSliceContains checks if a given string is contained in a slice 64 // When anybody asks why Go needs generics, here you go. 65 func strSliceContains(haystack []string, needle string) bool { 66 for _, s := range haystack { 67 if s == needle { 68 return true 69 } 70 } 71 return false 72 }