resourcemanager.go 1.3 KB

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