github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/xsync/last_usage_guard.go (about)

     1  package xsync
     2  
     3  import (
     4  	"sync/atomic"
     5  	"time"
     6  
     7  	"github.com/jonboulle/clockwork"
     8  )
     9  
    10  type (
    11  	LastUsage interface {
    12  		Get() time.Time
    13  		Start() (stop func())
    14  	}
    15  	lastUsage struct {
    16  		locks atomic.Int64
    17  		t     atomic.Pointer[time.Time]
    18  		clock clockwork.Clock
    19  	}
    20  	lastUsageOption func(g *lastUsage)
    21  )
    22  
    23  func WithClock(clock clockwork.Clock) lastUsageOption {
    24  	return func(g *lastUsage) {
    25  		g.clock = clock
    26  	}
    27  }
    28  
    29  func NewLastUsage(opts ...lastUsageOption) *lastUsage {
    30  	lastUsage := &lastUsage{
    31  		clock: clockwork.NewRealClock(),
    32  	}
    33  	for _, opt := range opts {
    34  		opt(lastUsage)
    35  	}
    36  
    37  	now := lastUsage.clock.Now()
    38  
    39  	lastUsage.t.Store(&now)
    40  
    41  	return lastUsage
    42  }
    43  
    44  func (guard *lastUsage) Get() time.Time {
    45  	if guard.locks.Load() == 0 {
    46  		return *guard.t.Load()
    47  	}
    48  
    49  	return guard.clock.Now()
    50  }