From 490241d63995e0b60d787e22318626d94edcad4b Mon Sep 17 00:00:00 2001 From: Kevin Wan Date: Sun, 28 Feb 2021 16:16:22 +0800 Subject: [PATCH] fix golint issues in core/syncx (#526) --- core/stat/internal/cpu_other.go | 1 + core/syncx/atomicbool.go | 6 ++++++ core/syncx/atomicduration.go | 6 ++++++ core/syncx/atomicfloat64.go | 7 +++++++ core/syncx/barrier.go | 2 ++ core/syncx/cond.go | 6 ++++-- core/syncx/donechan.go | 4 ++++ core/syncx/immutableresource.go | 4 ++++ core/syncx/lockedcalls.go | 1 + core/syncx/managedresource.go | 4 ++++ core/syncx/once.go | 1 + core/syncx/onceguard.go | 3 +++ core/syncx/pool.go | 10 ++++++++++ core/syncx/refresource.go | 5 +++++ core/syncx/resourcemanager.go | 4 ++++ core/syncx/sharedcalls.go | 1 + core/syncx/spinlock.go | 4 ++++ core/syncx/timeoutlimit.go | 6 ++++++ 18 files changed, 73 insertions(+), 2 deletions(-) diff --git a/core/stat/internal/cpu_other.go b/core/stat/internal/cpu_other.go index ddd6165d..ddc33072 100644 --- a/core/stat/internal/cpu_other.go +++ b/core/stat/internal/cpu_other.go @@ -2,6 +2,7 @@ package internal +// RefreshCpu returns cpu usage, always returns 0 on systems other than linux. func RefreshCpu() uint64 { return 0 } diff --git a/core/syncx/atomicbool.go b/core/syncx/atomicbool.go index 28710df5..7e489d9b 100644 --- a/core/syncx/atomicbool.go +++ b/core/syncx/atomicbool.go @@ -2,18 +2,22 @@ package syncx import "sync/atomic" +// An AtomicBool is an atomic implementation for boolean values. type AtomicBool uint32 +// NewAtomicBool returns an AtomicBool. func NewAtomicBool() *AtomicBool { return new(AtomicBool) } +// ForAtomicBool returns an AtomicBool with given val. func ForAtomicBool(val bool) *AtomicBool { b := NewAtomicBool() b.Set(val) return b } +// CompareAndSwap compares current value with given old, if equals, set to given val. func (b *AtomicBool) CompareAndSwap(old, val bool) bool { var ov, nv uint32 if old { @@ -25,6 +29,7 @@ func (b *AtomicBool) CompareAndSwap(old, val bool) bool { return atomic.CompareAndSwapUint32((*uint32)(b), ov, nv) } +// Set sets the value to v. func (b *AtomicBool) Set(v bool) { if v { atomic.StoreUint32((*uint32)(b), 1) @@ -33,6 +38,7 @@ func (b *AtomicBool) Set(v bool) { } } +// True returns true if current value is true. func (b *AtomicBool) True() bool { return atomic.LoadUint32((*uint32)(b)) == 1 } diff --git a/core/syncx/atomicduration.go b/core/syncx/atomicduration.go index 83c1ed4b..3ae12c6d 100644 --- a/core/syncx/atomicduration.go +++ b/core/syncx/atomicduration.go @@ -5,26 +5,32 @@ import ( "time" ) +// An AtomicDuration is an implementation of atomic duration. type AtomicDuration int64 +// NewAtomicDuration returns an AtomicDuration. func NewAtomicDuration() *AtomicDuration { return new(AtomicDuration) } +// ForAtomicDuration returns an AtomicDuration with given value. func ForAtomicDuration(val time.Duration) *AtomicDuration { d := NewAtomicDuration() d.Set(val) return d } +// CompareAndSwap compares current value with old, if equals, set the value to val. func (d *AtomicDuration) CompareAndSwap(old, val time.Duration) bool { return atomic.CompareAndSwapInt64((*int64)(d), int64(old), int64(val)) } +// Load loads the current duration. func (d *AtomicDuration) Load() time.Duration { return time.Duration(atomic.LoadInt64((*int64)(d))) } +// Set sets the value to val. func (d *AtomicDuration) Set(val time.Duration) { atomic.StoreInt64((*int64)(d), int64(val)) } diff --git a/core/syncx/atomicfloat64.go b/core/syncx/atomicfloat64.go index 35dd41cf..0ebead80 100644 --- a/core/syncx/atomicfloat64.go +++ b/core/syncx/atomicfloat64.go @@ -5,18 +5,22 @@ import ( "sync/atomic" ) +// An AtomicFloat64 is an implementation of atomic float64. type AtomicFloat64 uint64 +// NewAtomicFloat64 returns an AtomicFloat64. func NewAtomicFloat64() *AtomicFloat64 { return new(AtomicFloat64) } +// ForAtomicFloat64 returns an AtomicFloat64 with given val. func ForAtomicFloat64(val float64) *AtomicFloat64 { f := NewAtomicFloat64() f.Set(val) return f } +// Add adds val to current value. func (f *AtomicFloat64) Add(val float64) float64 { for { old := f.Load() @@ -27,14 +31,17 @@ func (f *AtomicFloat64) Add(val float64) float64 { } } +// CompareAndSwap compares current value with old, if equals, set the value to val. func (f *AtomicFloat64) CompareAndSwap(old, val float64) bool { return atomic.CompareAndSwapUint64((*uint64)(f), math.Float64bits(old), math.Float64bits(val)) } +// Load loads the current value. func (f *AtomicFloat64) Load() float64 { return math.Float64frombits(atomic.LoadUint64((*uint64)(f))) } +// Set sets the current value to val. func (f *AtomicFloat64) Set(val float64) { atomic.StoreUint64((*uint64)(f), math.Float64bits(val)) } diff --git a/core/syncx/barrier.go b/core/syncx/barrier.go index 9ee2d5ff..f790bcfd 100644 --- a/core/syncx/barrier.go +++ b/core/syncx/barrier.go @@ -2,10 +2,12 @@ package syncx import "sync" +// A Barrier is used to facility the barrier on a resource. type Barrier struct { lock sync.Mutex } +// Guard guards the given fn on the resource. func (b *Barrier) Guard(fn func()) { b.lock.Lock() defer b.lock.Unlock() diff --git a/core/syncx/cond.go b/core/syncx/cond.go index 5497beb7..e3e6368a 100644 --- a/core/syncx/cond.go +++ b/core/syncx/cond.go @@ -7,17 +7,19 @@ import ( "github.com/tal-tech/go-zero/core/timex" ) +// A Cond is used to wait for conditions. type Cond struct { signal chan lang.PlaceholderType } +// NewCond returns a Cond. func NewCond() *Cond { return &Cond{ signal: make(chan lang.PlaceholderType), } } -// WaitWithTimeout wait for signal return remain wait time or timed out +// WaitWithTimeout wait for signal return remain wait time or timed out. func (cond *Cond) WaitWithTimeout(timeout time.Duration) (time.Duration, bool) { timer := time.NewTimer(timeout) defer timer.Stop() @@ -33,7 +35,7 @@ func (cond *Cond) WaitWithTimeout(timeout time.Duration) (time.Duration, bool) { } } -// Wait for signal +// Wait waits for signals. func (cond *Cond) Wait() { <-cond.signal } diff --git a/core/syncx/donechan.go b/core/syncx/donechan.go index 6cb60b6f..1076460b 100644 --- a/core/syncx/donechan.go +++ b/core/syncx/donechan.go @@ -6,23 +6,27 @@ import ( "github.com/tal-tech/go-zero/core/lang" ) +// A DoneChan is used as a channel that can be closed multiple times and wait for done. type DoneChan struct { done chan lang.PlaceholderType once sync.Once } +// NewDoneChan returns a DoneChan. func NewDoneChan() *DoneChan { return &DoneChan{ done: make(chan lang.PlaceholderType), } } +// Close closes dc, it's safe to close more than once. func (dc *DoneChan) Close() { dc.once.Do(func() { close(dc.done) }) } +// Done returns a channel that can be notified on dc closed. func (dc *DoneChan) Done() chan lang.PlaceholderType { return dc.done } diff --git a/core/syncx/immutableresource.go b/core/syncx/immutableresource.go index 50339784..b607c250 100644 --- a/core/syncx/immutableresource.go +++ b/core/syncx/immutableresource.go @@ -10,8 +10,10 @@ import ( const defaultRefreshInterval = time.Second type ( + // ImmutableResourceOption defines the method to customize an ImmutableResource. ImmutableResourceOption func(resource *ImmutableResource) + // An ImmutableResource is used to manage an immutable resource. ImmutableResource struct { fetch func() (interface{}, error) resource interface{} @@ -22,6 +24,7 @@ type ( } ) +// NewImmutableResource returns an ImmutableResource. func NewImmutableResource(fn func() (interface{}, error), opts ...ImmutableResourceOption) *ImmutableResource { // cannot use executors.LessExecutor because of cycle imports ir := ImmutableResource{ @@ -35,6 +38,7 @@ func NewImmutableResource(fn func() (interface{}, error), opts ...ImmutableResou return &ir } +// Get gets the immutable resource, fetches automatically if not loaded. func (ir *ImmutableResource) Get() (interface{}, error) { ir.lock.RLock() resource := ir.resource diff --git a/core/syncx/lockedcalls.go b/core/syncx/lockedcalls.go index e2dd0fac..3b7f1b3f 100644 --- a/core/syncx/lockedcalls.go +++ b/core/syncx/lockedcalls.go @@ -19,6 +19,7 @@ type ( } ) +// NewLockedCalls returns a LockedCalls. func NewLockedCalls() LockedCalls { return &lockedGroup{ m: make(map[string]*sync.WaitGroup), diff --git a/core/syncx/managedresource.go b/core/syncx/managedresource.go index f231d671..65d85162 100644 --- a/core/syncx/managedresource.go +++ b/core/syncx/managedresource.go @@ -2,6 +2,7 @@ package syncx import "sync" +// A ManagedResource is used to manage a resource that might be broken and refetched, like a connection. type ManagedResource struct { resource interface{} lock sync.RWMutex @@ -9,6 +10,7 @@ type ManagedResource struct { equals func(a, b interface{}) bool } +// NewManagedResource returns a ManagedResource. func NewManagedResource(generate func() interface{}, equals func(a, b interface{}) bool) *ManagedResource { return &ManagedResource{ generate: generate, @@ -16,6 +18,7 @@ func NewManagedResource(generate func() interface{}, equals func(a, b interface{ } } +// MarkBroken marks the resouce broken. func (mr *ManagedResource) MarkBroken(resource interface{}) { mr.lock.Lock() defer mr.lock.Unlock() @@ -25,6 +28,7 @@ func (mr *ManagedResource) MarkBroken(resource interface{}) { } } +// Take takes the resource, if not loaded, generates it. func (mr *ManagedResource) Take() interface{} { mr.lock.RLock() resource := mr.resource diff --git a/core/syncx/once.go b/core/syncx/once.go index 1a51f9bd..992d5102 100644 --- a/core/syncx/once.go +++ b/core/syncx/once.go @@ -2,6 +2,7 @@ package syncx import "sync" +// Once returns a func that guanartees fn can only called once. func Once(fn func()) func() { once := new(sync.Once) return func() { diff --git a/core/syncx/onceguard.go b/core/syncx/onceguard.go index a4f232eb..b4afd5ee 100644 --- a/core/syncx/onceguard.go +++ b/core/syncx/onceguard.go @@ -2,14 +2,17 @@ package syncx import "sync/atomic" +// A OnceGuard is used to make sure a resouce can be taken once. type OnceGuard struct { done uint32 } +// Taken checks if the resource is taken. func (og *OnceGuard) Taken() bool { return atomic.LoadUint32(&og.done) == 1 } +// Take takes the resource, returns true on success, false for otherwise. func (og *OnceGuard) Take() bool { return atomic.CompareAndSwapUint32(&og.done, 0, 1) } diff --git a/core/syncx/pool.go b/core/syncx/pool.go index 93444026..983c7562 100644 --- a/core/syncx/pool.go +++ b/core/syncx/pool.go @@ -8,6 +8,7 @@ import ( ) type ( + // PoolOption defines the method to customize a Pool. PoolOption func(*Pool) node struct { @@ -16,6 +17,11 @@ type ( lastUsed time.Duration } + // A Pool is used to pool resources. + // The difference between sync.Pool is that: + // 1. the limit of the resouces + // 2. max age of the resources can be set + // 3. the method to destroy resources can be customized Pool struct { limit int created int @@ -28,6 +34,7 @@ type ( } ) +// NewPool returns a Pool. func NewPool(n int, create func() interface{}, destroy func(interface{}), opts ...PoolOption) *Pool { if n <= 0 { panic("pool size can't be negative or zero") @@ -49,6 +56,7 @@ func NewPool(n int, create func() interface{}, destroy func(interface{}), opts . return pool } +// Get gets a resouce. func (p *Pool) Get() interface{} { p.lock.Lock() defer p.lock.Unlock() @@ -75,6 +83,7 @@ func (p *Pool) Get() interface{} { } } +// Put puts a resource back. func (p *Pool) Put(x interface{}) { if x == nil { return @@ -91,6 +100,7 @@ func (p *Pool) Put(x interface{}) { p.cond.Signal() } +// WithMaxAge returns a function to customize a Pool with given max age. func WithMaxAge(duration time.Duration) PoolOption { return func(pool *Pool) { pool.maxAge = duration diff --git a/core/syncx/refresource.go b/core/syncx/refresource.go index f87fc61f..cc6a224f 100644 --- a/core/syncx/refresource.go +++ b/core/syncx/refresource.go @@ -5,8 +5,10 @@ import ( "sync" ) +// ErrUseOfCleaned is an error that indicates using a cleaned resource. var ErrUseOfCleaned = errors.New("using a cleaned resource") +// A RefResource is used to reference counting a resouce. type RefResource struct { lock sync.Mutex ref int32 @@ -14,12 +16,14 @@ type RefResource struct { clean func() } +// NewRefResource returns a RefResource. func NewRefResource(clean func()) *RefResource { return &RefResource{ clean: clean, } } +// Use uses the resource with reference count incremented. func (r *RefResource) Use() error { r.lock.Lock() defer r.lock.Unlock() @@ -32,6 +36,7 @@ func (r *RefResource) Use() error { return nil } +// Clean cleans a resource with reference count decremented. func (r *RefResource) Clean() { r.lock.Lock() defer r.lock.Unlock() diff --git a/core/syncx/resourcemanager.go b/core/syncx/resourcemanager.go index 358bd994..04e03418 100644 --- a/core/syncx/resourcemanager.go +++ b/core/syncx/resourcemanager.go @@ -7,12 +7,14 @@ import ( "github.com/tal-tech/go-zero/core/errorx" ) +// A ResourceManager is a manager that used to manage resources. type ResourceManager struct { resources map[string]io.Closer sharedCalls SharedCalls lock sync.RWMutex } +// NewResourceManager returns a ResourceManager. func NewResourceManager() *ResourceManager { return &ResourceManager{ resources: make(map[string]io.Closer), @@ -20,6 +22,7 @@ func NewResourceManager() *ResourceManager { } } +// Close closes the manager. func (manager *ResourceManager) Close() error { manager.lock.Lock() defer manager.lock.Unlock() @@ -34,6 +37,7 @@ func (manager *ResourceManager) Close() error { return be.Err() } +// GetResource returns the resource associated with given key. func (manager *ResourceManager) GetResource(key string, create func() (io.Closer, error)) (io.Closer, error) { val, err := manager.sharedCalls.Do(key, func() (interface{}, error) { manager.lock.RLock() diff --git a/core/syncx/sharedcalls.go b/core/syncx/sharedcalls.go index c9b07857..4df1730d 100644 --- a/core/syncx/sharedcalls.go +++ b/core/syncx/sharedcalls.go @@ -26,6 +26,7 @@ type ( } ) +// NewSharedCalls returns a SharedCalls. func NewSharedCalls() SharedCalls { return &sharedGroup{ calls: make(map[string]*call), diff --git a/core/syncx/spinlock.go b/core/syncx/spinlock.go index c4966d2e..4736be4e 100644 --- a/core/syncx/spinlock.go +++ b/core/syncx/spinlock.go @@ -5,20 +5,24 @@ import ( "sync/atomic" ) +// A SpinLock is used as a lock a fast execution. type SpinLock struct { lock uint32 } +// Lock locks the SpinLock. func (sl *SpinLock) Lock() { for !sl.TryLock() { runtime.Gosched() } } +// TryLock tries to lock the SpinLock. func (sl *SpinLock) TryLock() bool { return atomic.CompareAndSwapUint32(&sl.lock, 0, 1) } +// Unlock unlocks the SpinLock. func (sl *SpinLock) Unlock() { atomic.StoreUint32(&sl.lock, 0) } diff --git a/core/syncx/timeoutlimit.go b/core/syncx/timeoutlimit.go index 802c9629..7fec353a 100644 --- a/core/syncx/timeoutlimit.go +++ b/core/syncx/timeoutlimit.go @@ -5,13 +5,16 @@ import ( "time" ) +// ErrTimeout is an error that indicates the borrow timeout. var ErrTimeout = errors.New("borrow timeout") +// A TimeoutLimit is used to borrow with timeouts. type TimeoutLimit struct { limit Limit cond *Cond } +// NewTimeoutLimit returns a TimeoutLimit. func NewTimeoutLimit(n int) TimeoutLimit { return TimeoutLimit{ limit: NewLimit(n), @@ -19,6 +22,7 @@ func NewTimeoutLimit(n int) TimeoutLimit { } } +// Borrow borrows with given timeout. func (l TimeoutLimit) Borrow(timeout time.Duration) error { if l.TryBorrow() { return nil @@ -37,6 +41,7 @@ func (l TimeoutLimit) Borrow(timeout time.Duration) error { } } +// Return returns a borrow. func (l TimeoutLimit) Return() error { if err := l.limit.Return(); err != nil { return err @@ -46,6 +51,7 @@ func (l TimeoutLimit) Return() error { return nil } +// TryBorrow tries a borrow. func (l TimeoutLimit) TryBorrow() bool { return l.limit.TryBorrow() }