content: refactor content store for API
After iterating on the GRPC API, the changes required for the actual implementation are now included in the content store. The begin change is the move to a single, atomic `Ingester.Writer` method for locking content ingestion on a key. From this, comes several new interface definitions. The main benefit here is the clarification between `Status` and `Info` that came out of the GPRC API. `Status` tells the status of a write, whereas `Info` is for querying metadata about various blobs. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
package content
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
"github.com/nightlyone/lockfile"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// In addition to providing inter-process locks for content ingest, we also
|
||||
@@ -16,6 +16,8 @@ import (
|
||||
// error reporting.
|
||||
|
||||
var (
|
||||
errLocked = errors.New("key is locked")
|
||||
|
||||
// locks lets us lock in process, as well as output of process.
|
||||
locks = map[lockfile.Lockfile]struct{}{}
|
||||
locksMu sync.Mutex
|
||||
@@ -26,11 +28,15 @@ func tryLock(lock lockfile.Lockfile) error {
|
||||
defer locksMu.Unlock()
|
||||
|
||||
if _, ok := locks[lock]; ok {
|
||||
return errors.New("file in use")
|
||||
return errLocked
|
||||
}
|
||||
|
||||
if err := lock.TryLock(); err != nil {
|
||||
return err
|
||||
if errors.Cause(err) == lockfile.ErrBusy {
|
||||
return errLocked
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "lock.TryLock() encountered an error")
|
||||
}
|
||||
|
||||
locks[lock] = struct{}{}
|
||||
|
Reference in New Issue
Block a user