fix golint issues in core/syncx (#526)

This commit is contained in:
Kevin Wan
2021-02-28 16:16:22 +08:00
committed by GitHub
parent f02711a9cb
commit 490241d639
18 changed files with 73 additions and 2 deletions

View File

@@ -2,6 +2,7 @@
package internal package internal
// RefreshCpu returns cpu usage, always returns 0 on systems other than linux.
func RefreshCpu() uint64 { func RefreshCpu() uint64 {
return 0 return 0
} }

View File

@@ -2,18 +2,22 @@ package syncx
import "sync/atomic" import "sync/atomic"
// An AtomicBool is an atomic implementation for boolean values.
type AtomicBool uint32 type AtomicBool uint32
// NewAtomicBool returns an AtomicBool.
func NewAtomicBool() *AtomicBool { func NewAtomicBool() *AtomicBool {
return new(AtomicBool) return new(AtomicBool)
} }
// ForAtomicBool returns an AtomicBool with given val.
func ForAtomicBool(val bool) *AtomicBool { func ForAtomicBool(val bool) *AtomicBool {
b := NewAtomicBool() b := NewAtomicBool()
b.Set(val) b.Set(val)
return b return b
} }
// CompareAndSwap compares current value with given old, if equals, set to given val.
func (b *AtomicBool) CompareAndSwap(old, val bool) bool { func (b *AtomicBool) CompareAndSwap(old, val bool) bool {
var ov, nv uint32 var ov, nv uint32
if old { if old {
@@ -25,6 +29,7 @@ func (b *AtomicBool) CompareAndSwap(old, val bool) bool {
return atomic.CompareAndSwapUint32((*uint32)(b), ov, nv) return atomic.CompareAndSwapUint32((*uint32)(b), ov, nv)
} }
// Set sets the value to v.
func (b *AtomicBool) Set(v bool) { func (b *AtomicBool) Set(v bool) {
if v { if v {
atomic.StoreUint32((*uint32)(b), 1) 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 { func (b *AtomicBool) True() bool {
return atomic.LoadUint32((*uint32)(b)) == 1 return atomic.LoadUint32((*uint32)(b)) == 1
} }

View File

@@ -5,26 +5,32 @@ import (
"time" "time"
) )
// An AtomicDuration is an implementation of atomic duration.
type AtomicDuration int64 type AtomicDuration int64
// NewAtomicDuration returns an AtomicDuration.
func NewAtomicDuration() *AtomicDuration { func NewAtomicDuration() *AtomicDuration {
return new(AtomicDuration) return new(AtomicDuration)
} }
// ForAtomicDuration returns an AtomicDuration with given value.
func ForAtomicDuration(val time.Duration) *AtomicDuration { func ForAtomicDuration(val time.Duration) *AtomicDuration {
d := NewAtomicDuration() d := NewAtomicDuration()
d.Set(val) d.Set(val)
return d return d
} }
// CompareAndSwap compares current value with old, if equals, set the value to val.
func (d *AtomicDuration) CompareAndSwap(old, val time.Duration) bool { func (d *AtomicDuration) CompareAndSwap(old, val time.Duration) bool {
return atomic.CompareAndSwapInt64((*int64)(d), int64(old), int64(val)) return atomic.CompareAndSwapInt64((*int64)(d), int64(old), int64(val))
} }
// Load loads the current duration.
func (d *AtomicDuration) Load() time.Duration { func (d *AtomicDuration) Load() time.Duration {
return time.Duration(atomic.LoadInt64((*int64)(d))) return time.Duration(atomic.LoadInt64((*int64)(d)))
} }
// Set sets the value to val.
func (d *AtomicDuration) Set(val time.Duration) { func (d *AtomicDuration) Set(val time.Duration) {
atomic.StoreInt64((*int64)(d), int64(val)) atomic.StoreInt64((*int64)(d), int64(val))
} }

View File

@@ -5,18 +5,22 @@ import (
"sync/atomic" "sync/atomic"
) )
// An AtomicFloat64 is an implementation of atomic float64.
type AtomicFloat64 uint64 type AtomicFloat64 uint64
// NewAtomicFloat64 returns an AtomicFloat64.
func NewAtomicFloat64() *AtomicFloat64 { func NewAtomicFloat64() *AtomicFloat64 {
return new(AtomicFloat64) return new(AtomicFloat64)
} }
// ForAtomicFloat64 returns an AtomicFloat64 with given val.
func ForAtomicFloat64(val float64) *AtomicFloat64 { func ForAtomicFloat64(val float64) *AtomicFloat64 {
f := NewAtomicFloat64() f := NewAtomicFloat64()
f.Set(val) f.Set(val)
return f return f
} }
// Add adds val to current value.
func (f *AtomicFloat64) Add(val float64) float64 { func (f *AtomicFloat64) Add(val float64) float64 {
for { for {
old := f.Load() 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 { func (f *AtomicFloat64) CompareAndSwap(old, val float64) bool {
return atomic.CompareAndSwapUint64((*uint64)(f), math.Float64bits(old), math.Float64bits(val)) return atomic.CompareAndSwapUint64((*uint64)(f), math.Float64bits(old), math.Float64bits(val))
} }
// Load loads the current value.
func (f *AtomicFloat64) Load() float64 { func (f *AtomicFloat64) Load() float64 {
return math.Float64frombits(atomic.LoadUint64((*uint64)(f))) return math.Float64frombits(atomic.LoadUint64((*uint64)(f)))
} }
// Set sets the current value to val.
func (f *AtomicFloat64) Set(val float64) { func (f *AtomicFloat64) Set(val float64) {
atomic.StoreUint64((*uint64)(f), math.Float64bits(val)) atomic.StoreUint64((*uint64)(f), math.Float64bits(val))
} }

View File

@@ -2,10 +2,12 @@ package syncx
import "sync" import "sync"
// A Barrier is used to facility the barrier on a resource.
type Barrier struct { type Barrier struct {
lock sync.Mutex lock sync.Mutex
} }
// Guard guards the given fn on the resource.
func (b *Barrier) Guard(fn func()) { func (b *Barrier) Guard(fn func()) {
b.lock.Lock() b.lock.Lock()
defer b.lock.Unlock() defer b.lock.Unlock()

View File

@@ -7,17 +7,19 @@ import (
"github.com/tal-tech/go-zero/core/timex" "github.com/tal-tech/go-zero/core/timex"
) )
// A Cond is used to wait for conditions.
type Cond struct { type Cond struct {
signal chan lang.PlaceholderType signal chan lang.PlaceholderType
} }
// NewCond returns a Cond.
func NewCond() *Cond { func NewCond() *Cond {
return &Cond{ return &Cond{
signal: make(chan lang.PlaceholderType), 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) { func (cond *Cond) WaitWithTimeout(timeout time.Duration) (time.Duration, bool) {
timer := time.NewTimer(timeout) timer := time.NewTimer(timeout)
defer timer.Stop() 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() { func (cond *Cond) Wait() {
<-cond.signal <-cond.signal
} }

View File

@@ -6,23 +6,27 @@ import (
"github.com/tal-tech/go-zero/core/lang" "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 { type DoneChan struct {
done chan lang.PlaceholderType done chan lang.PlaceholderType
once sync.Once once sync.Once
} }
// NewDoneChan returns a DoneChan.
func NewDoneChan() *DoneChan { func NewDoneChan() *DoneChan {
return &DoneChan{ return &DoneChan{
done: make(chan lang.PlaceholderType), done: make(chan lang.PlaceholderType),
} }
} }
// Close closes dc, it's safe to close more than once.
func (dc *DoneChan) Close() { func (dc *DoneChan) Close() {
dc.once.Do(func() { dc.once.Do(func() {
close(dc.done) close(dc.done)
}) })
} }
// Done returns a channel that can be notified on dc closed.
func (dc *DoneChan) Done() chan lang.PlaceholderType { func (dc *DoneChan) Done() chan lang.PlaceholderType {
return dc.done return dc.done
} }

View File

@@ -10,8 +10,10 @@ import (
const defaultRefreshInterval = time.Second const defaultRefreshInterval = time.Second
type ( type (
// ImmutableResourceOption defines the method to customize an ImmutableResource.
ImmutableResourceOption func(resource *ImmutableResource) ImmutableResourceOption func(resource *ImmutableResource)
// An ImmutableResource is used to manage an immutable resource.
ImmutableResource struct { ImmutableResource struct {
fetch func() (interface{}, error) fetch func() (interface{}, error)
resource interface{} resource interface{}
@@ -22,6 +24,7 @@ type (
} }
) )
// NewImmutableResource returns an ImmutableResource.
func NewImmutableResource(fn func() (interface{}, error), opts ...ImmutableResourceOption) *ImmutableResource { func NewImmutableResource(fn func() (interface{}, error), opts ...ImmutableResourceOption) *ImmutableResource {
// cannot use executors.LessExecutor because of cycle imports // cannot use executors.LessExecutor because of cycle imports
ir := ImmutableResource{ ir := ImmutableResource{
@@ -35,6 +38,7 @@ func NewImmutableResource(fn func() (interface{}, error), opts ...ImmutableResou
return &ir return &ir
} }
// Get gets the immutable resource, fetches automatically if not loaded.
func (ir *ImmutableResource) Get() (interface{}, error) { func (ir *ImmutableResource) Get() (interface{}, error) {
ir.lock.RLock() ir.lock.RLock()
resource := ir.resource resource := ir.resource

View File

@@ -19,6 +19,7 @@ type (
} }
) )
// NewLockedCalls returns a LockedCalls.
func NewLockedCalls() LockedCalls { func NewLockedCalls() LockedCalls {
return &lockedGroup{ return &lockedGroup{
m: make(map[string]*sync.WaitGroup), m: make(map[string]*sync.WaitGroup),

View File

@@ -2,6 +2,7 @@ package syncx
import "sync" import "sync"
// A ManagedResource is used to manage a resource that might be broken and refetched, like a connection.
type ManagedResource struct { type ManagedResource struct {
resource interface{} resource interface{}
lock sync.RWMutex lock sync.RWMutex
@@ -9,6 +10,7 @@ type ManagedResource struct {
equals func(a, b interface{}) bool equals func(a, b interface{}) bool
} }
// NewManagedResource returns a ManagedResource.
func NewManagedResource(generate func() interface{}, equals func(a, b interface{}) bool) *ManagedResource { func NewManagedResource(generate func() interface{}, equals func(a, b interface{}) bool) *ManagedResource {
return &ManagedResource{ return &ManagedResource{
generate: generate, 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{}) { func (mr *ManagedResource) MarkBroken(resource interface{}) {
mr.lock.Lock() mr.lock.Lock()
defer mr.lock.Unlock() 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{} { func (mr *ManagedResource) Take() interface{} {
mr.lock.RLock() mr.lock.RLock()
resource := mr.resource resource := mr.resource

View File

@@ -2,6 +2,7 @@ package syncx
import "sync" import "sync"
// Once returns a func that guanartees fn can only called once.
func Once(fn func()) func() { func Once(fn func()) func() {
once := new(sync.Once) once := new(sync.Once)
return func() { return func() {

View File

@@ -2,14 +2,17 @@ package syncx
import "sync/atomic" import "sync/atomic"
// A OnceGuard is used to make sure a resouce can be taken once.
type OnceGuard struct { type OnceGuard struct {
done uint32 done uint32
} }
// Taken checks if the resource is taken.
func (og *OnceGuard) Taken() bool { func (og *OnceGuard) Taken() bool {
return atomic.LoadUint32(&og.done) == 1 return atomic.LoadUint32(&og.done) == 1
} }
// Take takes the resource, returns true on success, false for otherwise.
func (og *OnceGuard) Take() bool { func (og *OnceGuard) Take() bool {
return atomic.CompareAndSwapUint32(&og.done, 0, 1) return atomic.CompareAndSwapUint32(&og.done, 0, 1)
} }

View File

@@ -8,6 +8,7 @@ import (
) )
type ( type (
// PoolOption defines the method to customize a Pool.
PoolOption func(*Pool) PoolOption func(*Pool)
node struct { node struct {
@@ -16,6 +17,11 @@ type (
lastUsed time.Duration 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 { Pool struct {
limit int limit int
created 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 { func NewPool(n int, create func() interface{}, destroy func(interface{}), opts ...PoolOption) *Pool {
if n <= 0 { if n <= 0 {
panic("pool size can't be negative or zero") 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 return pool
} }
// Get gets a resouce.
func (p *Pool) Get() interface{} { func (p *Pool) Get() interface{} {
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
@@ -75,6 +83,7 @@ func (p *Pool) Get() interface{} {
} }
} }
// Put puts a resource back.
func (p *Pool) Put(x interface{}) { func (p *Pool) Put(x interface{}) {
if x == nil { if x == nil {
return return
@@ -91,6 +100,7 @@ func (p *Pool) Put(x interface{}) {
p.cond.Signal() p.cond.Signal()
} }
// WithMaxAge returns a function to customize a Pool with given max age.
func WithMaxAge(duration time.Duration) PoolOption { func WithMaxAge(duration time.Duration) PoolOption {
return func(pool *Pool) { return func(pool *Pool) {
pool.maxAge = duration pool.maxAge = duration

View File

@@ -5,8 +5,10 @@ import (
"sync" "sync"
) )
// ErrUseOfCleaned is an error that indicates using a cleaned resource.
var ErrUseOfCleaned = errors.New("using a cleaned resource") var ErrUseOfCleaned = errors.New("using a cleaned resource")
// A RefResource is used to reference counting a resouce.
type RefResource struct { type RefResource struct {
lock sync.Mutex lock sync.Mutex
ref int32 ref int32
@@ -14,12 +16,14 @@ type RefResource struct {
clean func() clean func()
} }
// NewRefResource returns a RefResource.
func NewRefResource(clean func()) *RefResource { func NewRefResource(clean func()) *RefResource {
return &RefResource{ return &RefResource{
clean: clean, clean: clean,
} }
} }
// Use uses the resource with reference count incremented.
func (r *RefResource) Use() error { func (r *RefResource) Use() error {
r.lock.Lock() r.lock.Lock()
defer r.lock.Unlock() defer r.lock.Unlock()
@@ -32,6 +36,7 @@ func (r *RefResource) Use() error {
return nil return nil
} }
// Clean cleans a resource with reference count decremented.
func (r *RefResource) Clean() { func (r *RefResource) Clean() {
r.lock.Lock() r.lock.Lock()
defer r.lock.Unlock() defer r.lock.Unlock()

View File

@@ -7,12 +7,14 @@ import (
"github.com/tal-tech/go-zero/core/errorx" "github.com/tal-tech/go-zero/core/errorx"
) )
// A ResourceManager is a manager that used to manage resources.
type ResourceManager struct { type ResourceManager struct {
resources map[string]io.Closer resources map[string]io.Closer
sharedCalls SharedCalls sharedCalls SharedCalls
lock sync.RWMutex lock sync.RWMutex
} }
// NewResourceManager returns a ResourceManager.
func NewResourceManager() *ResourceManager { func NewResourceManager() *ResourceManager {
return &ResourceManager{ return &ResourceManager{
resources: make(map[string]io.Closer), resources: make(map[string]io.Closer),
@@ -20,6 +22,7 @@ func NewResourceManager() *ResourceManager {
} }
} }
// Close closes the manager.
func (manager *ResourceManager) Close() error { func (manager *ResourceManager) Close() error {
manager.lock.Lock() manager.lock.Lock()
defer manager.lock.Unlock() defer manager.lock.Unlock()
@@ -34,6 +37,7 @@ func (manager *ResourceManager) Close() error {
return be.Err() 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) { func (manager *ResourceManager) GetResource(key string, create func() (io.Closer, error)) (io.Closer, error) {
val, err := manager.sharedCalls.Do(key, func() (interface{}, error) { val, err := manager.sharedCalls.Do(key, func() (interface{}, error) {
manager.lock.RLock() manager.lock.RLock()

View File

@@ -26,6 +26,7 @@ type (
} }
) )
// NewSharedCalls returns a SharedCalls.
func NewSharedCalls() SharedCalls { func NewSharedCalls() SharedCalls {
return &sharedGroup{ return &sharedGroup{
calls: make(map[string]*call), calls: make(map[string]*call),

View File

@@ -5,20 +5,24 @@ import (
"sync/atomic" "sync/atomic"
) )
// A SpinLock is used as a lock a fast execution.
type SpinLock struct { type SpinLock struct {
lock uint32 lock uint32
} }
// Lock locks the SpinLock.
func (sl *SpinLock) Lock() { func (sl *SpinLock) Lock() {
for !sl.TryLock() { for !sl.TryLock() {
runtime.Gosched() runtime.Gosched()
} }
} }
// TryLock tries to lock the SpinLock.
func (sl *SpinLock) TryLock() bool { func (sl *SpinLock) TryLock() bool {
return atomic.CompareAndSwapUint32(&sl.lock, 0, 1) return atomic.CompareAndSwapUint32(&sl.lock, 0, 1)
} }
// Unlock unlocks the SpinLock.
func (sl *SpinLock) Unlock() { func (sl *SpinLock) Unlock() {
atomic.StoreUint32(&sl.lock, 0) atomic.StoreUint32(&sl.lock, 0)
} }

View File

@@ -5,13 +5,16 @@ import (
"time" "time"
) )
// ErrTimeout is an error that indicates the borrow timeout.
var ErrTimeout = errors.New("borrow timeout") var ErrTimeout = errors.New("borrow timeout")
// A TimeoutLimit is used to borrow with timeouts.
type TimeoutLimit struct { type TimeoutLimit struct {
limit Limit limit Limit
cond *Cond cond *Cond
} }
// NewTimeoutLimit returns a TimeoutLimit.
func NewTimeoutLimit(n int) TimeoutLimit { func NewTimeoutLimit(n int) TimeoutLimit {
return TimeoutLimit{ return TimeoutLimit{
limit: NewLimit(n), 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 { func (l TimeoutLimit) Borrow(timeout time.Duration) error {
if l.TryBorrow() { if l.TryBorrow() {
return nil return nil
@@ -37,6 +41,7 @@ func (l TimeoutLimit) Borrow(timeout time.Duration) error {
} }
} }
// Return returns a borrow.
func (l TimeoutLimit) Return() error { func (l TimeoutLimit) Return() error {
if err := l.limit.Return(); err != nil { if err := l.limit.Return(); err != nil {
return err return err
@@ -46,6 +51,7 @@ func (l TimeoutLimit) Return() error {
return nil return nil
} }
// TryBorrow tries a borrow.
func (l TimeoutLimit) TryBorrow() bool { func (l TimeoutLimit) TryBorrow() bool {
return l.limit.TryBorrow() return l.limit.TryBorrow()
} }