You can not 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.3 KiB
59 lines
1.3 KiB
package syncx |
|
|
|
import ( |
|
"io" |
|
"sync" |
|
) |
|
|
|
type ResourceManager struct { |
|
resource map[string]io.Closer |
|
singleFlight SingleFlight |
|
lock sync.Mutex |
|
} |
|
|
|
func NewResourceManager() *ResourceManager { |
|
return &ResourceManager{ |
|
resource: make(map[string]io.Closer), |
|
singleFlight: NewSingleFlight(), |
|
} |
|
} |
|
func (manager *ResourceManager) Close() error { |
|
manager.lock.Lock() |
|
defer manager.lock.Unlock() |
|
var be errorx.BatchError |
|
for _, resource := range manager.resource { |
|
if err := resource.Close(); err != nil { |
|
be.Add(err) |
|
} |
|
} |
|
manager.resource = nil |
|
return be.Err() |
|
} |
|
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.Lock() |
|
resource, ok := manager.resource[key] |
|
manager.lock.Unlock() |
|
if ok { |
|
return resource, nil |
|
} |
|
resource, err := create() |
|
if err != nil { |
|
return nil, err |
|
} |
|
manager.lock.Lock() |
|
defer manager.lock.Unlock() |
|
manager.resource[key] = resource |
|
return resource, nil |
|
}) |
|
if err != nil { |
|
return nil, err |
|
} |
|
return val.(io.Closer), nil |
|
} |
|
|
|
func (manager *ResourceManager) Inject(key string, resource io.Closer) { |
|
manager.lock.Lock() |
|
manager.resource[key] = resource |
|
manager.lock.Unlock() |
|
}
|
|
|