mirror of
https://github.com/zeromicro/go-zero.git
synced 2025-01-23 09:00:20 +08:00
fix golint issues in core/syncx (#526)
This commit is contained in:
parent
f02711a9cb
commit
490241d639
@ -2,6 +2,7 @@
|
||||
|
||||
package internal
|
||||
|
||||
// RefreshCpu returns cpu usage, always returns 0 on systems other than linux.
|
||||
func RefreshCpu() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -19,6 +19,7 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
// NewLockedCalls returns a LockedCalls.
|
||||
func NewLockedCalls() LockedCalls {
|
||||
return &lockedGroup{
|
||||
m: make(map[string]*sync.WaitGroup),
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -26,6 +26,7 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
// NewSharedCalls returns a SharedCalls.
|
||||
func NewSharedCalls() SharedCalls {
|
||||
return &sharedGroup{
|
||||
calls: make(map[string]*call),
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user