func NewWindow(n int, d time.Duration) (*Window, error) {
	if int(d.Nanoseconds())%n != 0 {
		return nil, ErrBucketSize
	}
	w := &Window{
		size: n,
		ring: seed(ring.New(n)),
	}
	go w.tick(time.Duration(int(d) / n))
	return w, nil
}
Create a new window of duration d containing n buckets.
package circuitry
import (
	"container/ring"
	"errors"
	"sync"
	"sync/atomic"
	"time"
)
var ErrBucketSize = errors.New("bucket duration and size must divide equally")
type bucket struct {
	failures      int64
	successes     int64
	shortcircuits int64
}
func (b *bucket) MarkShortCircuited() {
	atomic.AddInt64(&b.shortcircuits, 1)
}
func (b *bucket) MarkSuccess() {
	atomic.AddInt64(&b.successes, 1)
}
func (b *bucket) MarkFailure() {
	atomic.AddInt64(&b.failures, 1)
}
func (b *bucket) Total() int64 {
	return b.Failures() + b.Successes() + b.ShortCircuited()
}
func (b *bucket) Errors() int64 {
	return b.Failures() + b.ShortCircuited()
}
func (b *bucket) Successes() int64 {
	return atomic.LoadInt64(&b.successes)
}
func (b *bucket) Failures() int64 {
	return atomic.LoadInt64(&b.failures)
}
func (b *bucket) ShortCircuited() int64 {
	return atomic.LoadInt64(&b.shortcircuits)
}
func (b *bucket) Reset() {
	atomic.StoreInt64(&b.failures, 0)
	atomic.StoreInt64(&b.successes, 0)
	atomic.StoreInt64(&b.shortcircuits, 0)
}
type Window struct {
	size int
	ring *ring.Ring
	m    sync.RWMutex
}