github.com/pachyderm/pachyderm@v1.13.4/src/client/limit/limit.go (about) 1 // Package limit provides primitives to limit concurrency. 2 // 3 // Note that this is not to be confused with rate-limiting. With concurrency 4 // limiting (which is what this package does), you are limiting the number of 5 // operations that can be running at any given point in time. With rate 6 // limiting, you are limiting the number of operations that can be fired 7 // within a given time window. 8 // 9 // For instance, even if you limit concurrency to 1, you can still have N 10 // requests per second where N is an arbitrarily large number, given that 11 // each request takes 1/N second to complete. 12 package limit 13 14 // ConcurrencyLimiter limits the number of concurrent operations 15 // If the ConcurrencyLimiter is initialized with a concurrency of 0, then 16 // all of the following functions will be no-ops, meaning that an arbitrary 17 // concurrency is allowed. 18 type ConcurrencyLimiter interface { 19 // Acquire acquires the right to proceed. It blocks if the concurrency 20 // limit has been reached. 21 Acquire() 22 // Release signals that an operation has completed. 23 Release() 24 // Wait blocks until all operations that have called Acquire thus far 25 // are completed. 26 Wait() 27 } 28 29 // New returns a new ConcurrencyLimiter with the given limit 30 func New(concurrency int) ConcurrencyLimiter { 31 if concurrency == 0 { 32 return &noOpLimiter{} 33 } 34 return &concurrencyLimiter{make(chan struct{}, concurrency)} 35 } 36 37 type concurrencyLimiter struct { 38 sem chan struct{} 39 } 40 41 func (c *concurrencyLimiter) Acquire() { 42 c.sem <- struct{}{} 43 } 44 45 func (c *concurrencyLimiter) Release() { 46 select { 47 case <-c.sem: 48 default: 49 panic("Release called without matching Acquire") 50 } 51 } 52 53 func (c *concurrencyLimiter) Wait() { 54 for i := 0; i < cap(c.sem); i++ { 55 c.sem <- struct{}{} 56 } 57 } 58 59 type noOpLimiter struct{} 60 61 func (n *noOpLimiter) Acquire() {} 62 63 func (n *noOpLimiter) Release() {} 64 65 func (n *noOpLimiter) Wait() {}