func (w *window) Successes() int64 {
	return atomic.LoadInt64(&w.allSuccess)
}
Successes returns the total number of successes recorded in all buckets.
package circuitbreaker
import (
	"fmt"
	"sync/atomic"
	"time"
	"github.com/bytedance/gopkg/lang/syncx"
)
type bucket struct {
	failure int64
	success int64
	timeout int64
}
func (b *bucket) Reset() {
	atomic.StoreInt64(&b.failure, 0)
	atomic.StoreInt64(&b.success, 0)
	atomic.StoreInt64(&b.timeout, 0)
}
func (b *bucket) Fail() {
	atomic.AddInt64(&b.failure, 1)
}
func (b *bucket) Succeed() {
	atomic.AddInt64(&b.success, 1)
}
func (b *bucket) Timeout() {
	atomic.AddInt64(&b.timeout, 1)
}
func (b *bucket) Failures() int64 {
	return atomic.LoadInt64(&b.failure)
}
func (b *bucket) Successes() int64 {
	return atomic.LoadInt64(&b.success)
}
func (b *bucket) Timeouts() int64 {
	return atomic.LoadInt64(&b.timeout)
}
type window struct {
	rw      syncx.RWMutex
	oldest  int32     
	latest  int32     
	buckets []bucket  
	bucketTime time.Duration  
	bucketNums int32          
	inWindow   int32          
	allSuccess int64
	allFailure int64
	allTimeout int64
	errStart int64
	conseErr int64
}
func newWindow() metricer {
	m, _ := newWindowWithOptions(defaultBucketTime, defaultBucketNums)
	return m
}
func newWindowWithOptions(bucketTime time.Duration, bucketNums int32) (metricer, error) {
	if bucketNums < 100 {
		return nil, fmt.Errorf("BucketNums can't be less than 100")
	}
	w := new(window)
	w.rw = syncx.NewRWMutex()
	w.bucketNums = bucketNums
	w.bucketTime = bucketTime
	w.buckets = make([]bucket, w.bucketNums)
	w.Reset()
	return w, nil
}
func (w *window) Succeed() {
	rwx := w.rw.RLocker()
	rwx.Lock()
	b := w.getBucket()
	atomic.StoreInt64(&w.errStart, 0)
	atomic.StoreInt64(&w.conseErr, 0)
	atomic.AddInt64(&w.allSuccess, 1)
	rwx.Unlock()
	b.Succeed()
}
func (w *window) Fail() {
	w.rw.Lock()
	b := w.getBucket()
	atomic.AddInt64(&w.conseErr, 1)
	atomic.AddInt64(&w.allFailure, 1)
	if atomic.LoadInt64(&w.errStart) == 0 {
		atomic.StoreInt64(&w.errStart, time.Now().UnixNano())
	}
	w.rw.Unlock()
	b.Fail()
}
func (w *window) Timeout() {
	w.rw.Lock()
	b := w.getBucket()
	atomic.AddInt64(&w.conseErr, 1)
	atomic.AddInt64(&w.allTimeout, 1)
	if atomic.LoadInt64(&w.errStart) == 0 {
		atomic.StoreInt64(&w.errStart, time.Now().UnixNano())
	}
	w.rw.Unlock()
	b.Timeout()
}
func (w *window) Counts() (successes, failures, timeouts int64) {
	return w.Successes(), w.Failures(), w.Timeouts()
}