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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 73 additions and 2 deletions

View File

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

View File

@ -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
}

View File

@ -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))
}

View File

@ -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))
}

View File

@ -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()

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

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

View File

@ -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

View File

@ -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() {

View File

@ -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)
}

View File

@ -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

View File

@ -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()

View File

@ -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()

View File

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

View File

@ -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)
}

View File

@ -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()
}