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  }