func (b *Bucket) Wait(n int64) time.Duration {
	var rem int64
	if rem = n - b.Take(n); rem == 0 {
		return 0
	}
	var wait time.Duration
	for rem > 0 {
		wait += b.wait(rem)
		time.Sleep(wait)
		rem -= b.Take(rem)
	}
	return wait
}
Wait waits for n amount of tokens to be available.
If n tokens are immediatelly available it doesn't sleep.
Otherwise, it sleeps the minimum amount of time required for the remaining
tokens to be available. It returns the wait duration.

This method is thread-safe.
package tb
import (
	"math"
	"sync/atomic"
	"time"
)
type Bucket struct {
	inc      int64
	tokens   int64
	capacity int64
	freq     time.Duration
	closing  chan struct{}
}
func NewBucket(c int64, freq time.Duration) *Bucket {
	b := &Bucket{tokens: c, capacity: c, closing: make(chan struct{})}
	if freq == -1 {
		return b
	} else if evenFreq := time.Duration(1e9 / c); freq < evenFreq {
		freq = evenFreq
	}
	b.freq = freq
	b.inc = int64(math.Floor(.5 + (float64(c) * freq.Seconds())))
	go b.fill()
	return b
}
func (b *Bucket) Take(n int64) (taken int64) {
	for {
		if tokens := atomic.LoadInt64(&b.tokens); tokens == 0 {
			return 0
		} else if n <= tokens {
			if !atomic.CompareAndSwapInt64(&b.tokens, tokens, tokens-n) {
				continue
			}
			return n
		} else if atomic.CompareAndSwapInt64(&b.tokens, tokens, 0) {  
			return tokens
		}
	}
}
func (b *Bucket) Put(n int64) (added int64) {
	for {
		if tokens := atomic.LoadInt64(&b.tokens); tokens == b.capacity {
			return 0
		} else if left := b.capacity - tokens; n <= left {
			if !atomic.CompareAndSwapInt64(&b.tokens, tokens, tokens+n) {
				continue
			}
			return n
		} else if atomic.CompareAndSwapInt64(&b.tokens, tokens, b.capacity) {
			return left
		}
	}
}