123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- package syncx
- import (
- "io"
- "sync"
- "github.com/wuntsong-org/go-zero-plus/core/errorx"
- )
- // A ResourceManager is a manager that used to manage resources.
- type ResourceManager struct {
- resources map[string]io.Closer
- singleFlight SingleFlight
- lock sync.RWMutex
- }
- // NewResourceManager returns a ResourceManager.
- func NewResourceManager() *ResourceManager {
- return &ResourceManager{
- resources: make(map[string]io.Closer),
- singleFlight: NewSingleFlight(),
- }
- }
- // Close closes the manager.
- // Don't use the ResourceManager after Close() called.
- func (manager *ResourceManager) Close() error {
- manager.lock.Lock()
- defer manager.lock.Unlock()
- var be errorx.BatchError
- for _, resource := range manager.resources {
- if err := resource.Close(); err != nil {
- be.Add(err)
- }
- }
- // release resources to avoid using it later
- manager.resources = nil
- 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.singleFlight.Do(key, func() (any, error) {
- manager.lock.RLock()
- resource, ok := manager.resources[key]
- manager.lock.RUnlock()
- if ok {
- return resource, nil
- }
- resource, err := create()
- if err != nil {
- return nil, err
- }
- manager.lock.Lock()
- defer manager.lock.Unlock()
- manager.resources[key] = resource
- return resource, nil
- })
- if err != nil {
- return nil, err
- }
- return val.(io.Closer), nil
- }
- // Inject injects the resource associated with given key.
- func (manager *ResourceManager) Inject(key string, resource io.Closer) {
- manager.lock.Lock()
- manager.resources[key] = resource
- manager.lock.Unlock()
- }
|