Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 5 additions & 17 deletions cache/renew.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@ package cache
import (
"context"
"log"
"sync"
"time"

"github.com/sunshineplan/utils/container"
)

type item[T any] struct {
sync.Mutex
ctx context.Context
cancel context.CancelFunc
lifecycle time.Duration
value T
value container.Value[T]
fn func() (T, error)
}

Expand All @@ -23,16 +21,14 @@ func (i *item[T]) set(value T) {
if i.lifecycle > 0 {
i.ctx, i.cancel = context.WithTimeout(i.ctx, i.lifecycle)
}
i.value = value
i.value.Store(value)
}

func (i *item[T]) renew() T {
v, err := i.fn()
i.Lock()
defer i.Unlock()
if err != nil {
log.Print(err)
v = i.value
return i.value.Load()
}
i.set(v)
return v
Expand Down Expand Up @@ -92,17 +88,13 @@ func (c *CacheWithRenew[Key, Value]) Get(key Key) (value Value, ok bool) {
if i, ok = c.get(key); !ok {
return
}
i.Lock()
defer i.Unlock()
value = i.value
value = i.value.Load()
return
}

// Delete deletes the value for a key.
func (c *CacheWithRenew[Key, Value]) Delete(key Key) {
if i, ok := c.m.LoadAndDelete(key); ok {
i.Lock()
defer i.Unlock()
if i.cancel != nil {
i.cancel()
}
Expand All @@ -113,9 +105,7 @@ func (c *CacheWithRenew[Key, Value]) Delete(key Key) {
func (c *CacheWithRenew[Key, Value]) Swap(key Key, value Value) (previous Value, loaded bool) {
var i *item[Value]
if i, loaded = c.get(key); loaded {
i.Lock()
defer i.Unlock()
previous = i.value
previous = i.value.Load()
i.set(value)
}
return
Expand All @@ -125,8 +115,6 @@ func (c *CacheWithRenew[Key, Value]) Swap(key Key, value Value) (previous Value,
func (c *CacheWithRenew[Key, Value]) Clear() {
c.m.Range(func(key Key, i *item[Value]) bool {
c.m.Delete(key)
i.Lock()
defer i.Unlock()
if i.cancel != nil {
i.cancel()
}
Expand Down
46 changes: 46 additions & 0 deletions container/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,49 @@ func (v *Value[T]) Swap(new T) (old T) {
func (v *Value[T]) CompareAndSwap(old, new T) (swapped bool) {
return v.v.CompareAndSwap(old, new)
}

// An Int provides atomic operations on an integer value of type T.
// It is a generic wrapper around [atomic.Int64], allowing usage with
// signed integer types such as int, int8, int16, int32, and int64.
type Int[T ~int64 | ~int32 | ~int16 | ~int8 | ~int] struct {
v atomic.Int64
}

// Add atomically adds delta to the value and returns the new value.
func (v *Int[T]) Add(delta T) (new T) {
return T(v.v.Add(int64(delta)))
}

// And atomically performs a bitwise AND operation with mask and returns
// the previous value.
func (v *Int[T]) And(mask T) (old T) {
return T(v.v.And(int64(mask)))
}

// CompareAndSwap executes the compare-and-swap operation for the [Int].
// It compares the current value with old, and if they are equal,
// sets it to new and returns true. Otherwise, it returns false.
func (v *Int[T]) CompareAndSwap(old T, new T) (swapped bool) {
return v.v.CompareAndSwap(int64(old), int64(new))
}

// Load atomically loads and returns the current value.
func (v *Int[T]) Load() T {
return T(v.v.Load())
}

// Or atomically performs a bitwise OR operation with mask and returns
// the previous value.
func (v *Int[T]) Or(mask T) (old T) {
return T(v.v.Or(int64(mask)))
}

// Store atomically stores val into the [Int].
func (v *Int[T]) Store(val T) {
v.v.Store(int64(val))
}

// Swap atomically stores new into the [Int] and returns the previous value.
func (v *Int[T]) Swap(new T) (old T) {
return T(v.v.Swap(int64(new)))
}
6 changes: 3 additions & 3 deletions log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ func ErrorContext(ctx context.Context, msg string, args ...any) {
Default().ErrorContext(ctx, msg, args...)
}

// Handler returns the slog handler of the default Logger.
func Handler() slog.Handler {
return Default().Handler()
// SlogHandler returns the slog handler of the default Logger.
func SlogHandler() slog.Handler {
return Default().SlogHandler()
}

// Info logs a message at Info level using the default Logger.
Expand Down
4 changes: 2 additions & 2 deletions log/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ func (l *Logger) ErrorContext(ctx context.Context, msg string, args ...any) {
l.slog.Load().ErrorContext(ctx, msg, args...)
}

// Handler returns the current slog handler.
func (l *Logger) Handler() slog.Handler {
// SlogHandler returns the current slog handler.
func (l *Logger) SlogHandler() slog.Handler {
return l.slog.Load().Handler()
}

Expand Down
Loading
Loading