mirror of https://github.com/synctv-org/synctv
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			59 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
package refreshcache
 | 
						|
 | 
						|
import (
 | 
						|
	"sync"
 | 
						|
	"sync/atomic"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
type RefreshCache[T any] struct {
 | 
						|
	lock        sync.Mutex
 | 
						|
	last        int64
 | 
						|
	maxAge      int64
 | 
						|
	refreshFunc func() (T, error)
 | 
						|
	data        atomic.Pointer[T]
 | 
						|
}
 | 
						|
 | 
						|
func NewRefreshCache[T any](refreshFunc func() (T, error), maxAge time.Duration) *RefreshCache[T] {
 | 
						|
	if refreshFunc == nil {
 | 
						|
		panic("refreshFunc cannot be nil")
 | 
						|
	}
 | 
						|
	if maxAge <= 0 {
 | 
						|
		panic("maxAge must be positive")
 | 
						|
	}
 | 
						|
	return &RefreshCache[T]{
 | 
						|
		refreshFunc: refreshFunc,
 | 
						|
		maxAge:      int64(maxAge),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (r *RefreshCache[T]) Get() (data T, err error) {
 | 
						|
	if time.Now().UnixNano()-atomic.LoadInt64(&r.last) < r.maxAge {
 | 
						|
		return *r.data.Load(), nil
 | 
						|
	}
 | 
						|
	r.lock.Lock()
 | 
						|
	defer r.lock.Unlock()
 | 
						|
	if time.Now().UnixNano()-r.last < r.maxAge {
 | 
						|
		return *r.data.Load(), nil
 | 
						|
	}
 | 
						|
	defer func() {
 | 
						|
		if err == nil {
 | 
						|
			r.data.Store(&data)
 | 
						|
			atomic.StoreInt64(&r.last, time.Now().UnixNano())
 | 
						|
		}
 | 
						|
	}()
 | 
						|
	return r.refreshFunc()
 | 
						|
}
 | 
						|
 | 
						|
func (r *RefreshCache[T]) Refresh() (data T, err error) {
 | 
						|
	r.lock.Lock()
 | 
						|
	defer r.lock.Unlock()
 | 
						|
	defer func() {
 | 
						|
		if err == nil {
 | 
						|
			r.data.Store(&data)
 | 
						|
			atomic.StoreInt64(&r.last, time.Now().UnixNano())
 | 
						|
		}
 | 
						|
	}()
 | 
						|
	return r.refreshFunc()
 | 
						|
}
 |