Files
maddy/framework/resource/singleton.go

73 lines
1.3 KiB
Go

package resource
import (
"sync"
"github.com/foxcpp/maddy/framework/log"
)
// Singleton represents a set of resources identified by an unique key.
type Singleton[T Resource] struct {
log *log.Logger
lock sync.RWMutex
resources map[string]T
}
func NewSingleton[T Resource](log *log.Logger) *Singleton[T] {
return &Singleton[T]{
log: log,
resources: make(map[string]T),
}
}
func (s *Singleton[T]) GetOpen(key string, open func() (T, error)) (T, error) {
s.lock.Lock()
defer s.lock.Unlock()
existing, ok := s.resources[key]
if ok {
s.log.DebugMsg("resource reused", "key", key)
return existing, nil
}
res, err := open()
if err != nil {
var empty T
return empty, err
}
s.log.DebugMsg("new resource", "key", key)
s.resources[key] = res
return res, nil
}
func (s *Singleton[T]) CloseUnused(isUsed func(key string) bool) error {
s.lock.Lock()
defer s.lock.Unlock()
for key, res := range s.resources {
if isUsed(key) {
continue
}
s.log.DebugMsg("resource released", "key", key)
res.Close()
delete(s.resources, key)
}
return nil
}
func (s *Singleton[T]) Close() error {
s.lock.Lock()
defer s.lock.Unlock()
for key, res := range s.resources {
s.log.DebugMsg("resource released", "key", key)
res.Close()
delete(s.resources, key)
}
return nil
}