resourcemanager.go 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package syncx
  2. import (
  3. "io"
  4. "sync"
  5. "github.com/tal-tech/go-zero/core/errorx"
  6. )
  7. type ResourceManager struct {
  8. resources map[string]io.Closer
  9. sharedCalls SharedCalls
  10. lock sync.RWMutex
  11. }
  12. func NewResourceManager() *ResourceManager {
  13. return &ResourceManager{
  14. resources: make(map[string]io.Closer),
  15. sharedCalls: NewSharedCalls(),
  16. }
  17. }
  18. func (manager *ResourceManager) Close() error {
  19. manager.lock.Lock()
  20. defer manager.lock.Unlock()
  21. var be errorx.BatchError
  22. for _, resource := range manager.resources {
  23. if err := resource.Close(); err != nil {
  24. be.Add(err)
  25. }
  26. }
  27. return be.Err()
  28. }
  29. func (manager *ResourceManager) GetResource(key string, create func() (io.Closer, error)) (io.Closer, error) {
  30. val, err := manager.sharedCalls.Do(key, func() (interface{}, error) {
  31. manager.lock.RLock()
  32. resource, ok := manager.resources[key]
  33. manager.lock.RUnlock()
  34. if ok {
  35. return resource, nil
  36. }
  37. resource, err := create()
  38. if err != nil {
  39. return nil, err
  40. }
  41. manager.lock.Lock()
  42. manager.resources[key] = resource
  43. manager.lock.Unlock()
  44. return resource, nil
  45. })
  46. if err != nil {
  47. return nil, err
  48. }
  49. return val.(io.Closer), nil
  50. }