2022-09-02 19:23:33 +00:00
|
|
|
package registry
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2022-09-22 16:57:21 +00:00
|
|
|
"errors"
|
2022-09-02 19:23:33 +00:00
|
|
|
"sync"
|
|
|
|
|
|
|
|
"go.etcd.io/bbolt"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ObjSelector struct {
|
|
|
|
boltDB *bbolt.DB
|
|
|
|
mu sync.Mutex
|
|
|
|
lastId uint64
|
|
|
|
objStatus string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *ObjSelector) NextObject() (*ObjectInfo, error) {
|
|
|
|
var foundObj *ObjectInfo
|
|
|
|
err := o.boltDB.View(func(tx *bbolt.Tx) error {
|
|
|
|
b := tx.Bucket([]byte(bucketName))
|
|
|
|
if b == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
c := b.Cursor()
|
|
|
|
|
|
|
|
// We use mutex so that multiple VUs won't attempt to modify lastId simultaneously
|
|
|
|
// TODO: consider singleton channel that will produce those ids on demand
|
|
|
|
o.mu.Lock()
|
|
|
|
defer o.mu.Unlock()
|
|
|
|
|
|
|
|
// Establish the start position for searching the next object:
|
|
|
|
// If we should go from the beginning (lastId=0), then we start from the first element
|
|
|
|
// Otherwise we start from the key right after the lastId
|
|
|
|
var keyBytes, objBytes []byte
|
|
|
|
if o.lastId == 0 {
|
|
|
|
keyBytes, objBytes = c.First()
|
|
|
|
} else {
|
|
|
|
c.Seek(encodeId(o.lastId))
|
|
|
|
keyBytes, objBytes = c.Next()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Iterate over objects to find the next object in the target status
|
|
|
|
var obj ObjectInfo
|
|
|
|
for ; keyBytes != nil; keyBytes, objBytes = c.Next() {
|
|
|
|
if objBytes != nil {
|
|
|
|
if err := json.Unmarshal(objBytes, &obj); err != nil {
|
|
|
|
// Ignore malformed objects for now. Maybe it should be panic?
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// If we reached an object in the target status, stop iterating
|
|
|
|
if obj.Status == o.objStatus {
|
|
|
|
foundObj = &obj
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the last key
|
|
|
|
if keyBytes != nil {
|
|
|
|
o.lastId = decodeId(keyBytes)
|
2022-09-22 16:57:21 +00:00
|
|
|
return nil
|
2022-09-02 19:23:33 +00:00
|
|
|
}
|
|
|
|
|
2022-09-22 16:57:21 +00:00
|
|
|
return errors.New("no objects are available")
|
2022-09-02 19:23:33 +00:00
|
|
|
})
|
|
|
|
return foundObj, err
|
|
|
|
}
|