github.com/lingyao2333/mo-zero@v1.4.1/core/syncx/managedresource.go (about) 1 package syncx 2 3 import "sync" 4 5 // A ManagedResource is used to manage a resource that might be broken and refetched, like a connection. 6 type ManagedResource struct { 7 resource interface{} 8 lock sync.RWMutex 9 generate func() interface{} 10 equals func(a, b interface{}) bool 11 } 12 13 // NewManagedResource returns a ManagedResource. 14 func NewManagedResource(generate func() interface{}, equals func(a, b interface{}) bool) *ManagedResource { 15 return &ManagedResource{ 16 generate: generate, 17 equals: equals, 18 } 19 } 20 21 // MarkBroken marks the resource broken. 22 func (mr *ManagedResource) MarkBroken(resource interface{}) { 23 mr.lock.Lock() 24 defer mr.lock.Unlock() 25 26 if mr.equals(mr.resource, resource) { 27 mr.resource = nil 28 } 29 } 30 31 // Take takes the resource, if not loaded, generates it. 32 func (mr *ManagedResource) Take() interface{} { 33 mr.lock.RLock() 34 resource := mr.resource 35 mr.lock.RUnlock() 36 37 if resource != nil { 38 return resource 39 } 40 41 mr.lock.Lock() 42 defer mr.lock.Unlock() 43 // maybe another Take() call already generated the resource. 44 if mr.resource == nil { 45 mr.resource = mr.generate() 46 } 47 return mr.resource 48 }