mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			66 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			66 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
Locker
 | 
						|
=====
 | 
						|
 | 
						|
locker provides a mechanism for creating finer-grained locking to help
 | 
						|
free up more global locks to handle other tasks.
 | 
						|
 | 
						|
The implementation looks close to a sync.Mutex, however, the user must provide a
 | 
						|
reference to use to refer to the underlying lock when locking and unlocking,
 | 
						|
and unlock may generate an error.
 | 
						|
 | 
						|
If a lock with a given name does not exist when `Lock` is called, one is
 | 
						|
created.
 | 
						|
Lock references are automatically cleaned up on `Unlock` if nothing else is
 | 
						|
waiting for the lock.
 | 
						|
 | 
						|
 | 
						|
## Usage
 | 
						|
 | 
						|
```go
 | 
						|
package important
 | 
						|
 | 
						|
import (
 | 
						|
	"sync"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/moby/locker"
 | 
						|
)
 | 
						|
 | 
						|
type important struct {
 | 
						|
	locks *locker.Locker
 | 
						|
	data  map[string]interface{}
 | 
						|
	mu    sync.Mutex
 | 
						|
}
 | 
						|
 | 
						|
func (i *important) Get(name string) interface{} {
 | 
						|
	i.locks.Lock(name)
 | 
						|
	defer i.locks.Unlock(name)
 | 
						|
	return i.data[name]
 | 
						|
}
 | 
						|
 | 
						|
func (i *important) Create(name string, data interface{}) {
 | 
						|
	i.locks.Lock(name)
 | 
						|
	defer i.locks.Unlock(name)
 | 
						|
 | 
						|
	i.createImportant(data)
 | 
						|
 | 
						|
	i.mu.Lock()
 | 
						|
	i.data[name] = data
 | 
						|
	i.mu.Unlock()
 | 
						|
}
 | 
						|
 | 
						|
func (i *important) createImportant(data interface{}) {
 | 
						|
	time.Sleep(10 * time.Second)
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
For functions dealing with a given name, always lock at the beginning of the
 | 
						|
function (or before doing anything with the underlying state), this ensures any
 | 
						|
other function that is dealing with the same name will block.
 | 
						|
 | 
						|
When needing to modify the underlying data, use the global lock to ensure nothing
 | 
						|
else is modifying it at the same time.
 | 
						|
Since name lock is already in place, no reads will occur while the modification
 | 
						|
is being performed.
 | 
						|
 |