fix: synchronize DWH registry snapshots
This commit is contained in:
@@ -25,7 +25,10 @@ import (
|
||||
"github.com/aritmolab/thothii/tools/dwh-auth/internal/securefile"
|
||||
)
|
||||
|
||||
const maxRecordBytes = 4096
|
||||
const (
|
||||
maxRecordBytes = 4096
|
||||
registryLockName = ".writer.lock"
|
||||
)
|
||||
|
||||
// State describes which registry directory owns a public record.
|
||||
type State string
|
||||
@@ -155,12 +158,13 @@ func (s *Store) Find(keyID string) (record.Record, error) {
|
||||
if !validKeyID(keyID) {
|
||||
return record.Record{}, ErrNotFound
|
||||
}
|
||||
if s == nil {
|
||||
return record.Record{}, integrity(errors.New("uninitialized store"))
|
||||
}
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.findUnlocked(keyID)
|
||||
var value record.Record
|
||||
err := s.withReaderLock(func() error {
|
||||
var findErr error
|
||||
value, findErr = s.findUnlocked(keyID)
|
||||
return findErr
|
||||
})
|
||||
return value, err
|
||||
}
|
||||
|
||||
func (s *Store) findUnlocked(keyID string) (record.Record, error) {
|
||||
@@ -182,12 +186,13 @@ func (s *Store) findUnlocked(keyID string) (record.Record, error) {
|
||||
// FindLegacy returns the sole active legacy_raw record. A revoked legacy record
|
||||
// wins; any multiple-legacy condition is an integrity fault.
|
||||
func (s *Store) FindLegacy() (record.Record, error) {
|
||||
if s == nil {
|
||||
return record.Record{}, integrity(errors.New("uninitialized store"))
|
||||
}
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.findLegacyUnlocked()
|
||||
var value record.Record
|
||||
err := s.withReaderLock(func() error {
|
||||
var findErr error
|
||||
value, findErr = s.findLegacyUnlocked()
|
||||
return findErr
|
||||
})
|
||||
return value, err
|
||||
}
|
||||
|
||||
func (s *Store) findLegacyUnlocked() (record.Record, error) {
|
||||
@@ -217,12 +222,13 @@ func (s *Store) findLegacyUnlocked() (record.Record, error) {
|
||||
// List returns a stable, redacted inventory. A revoked record replaces any
|
||||
// same-key active record visible during a revoked-first transition.
|
||||
func (s *Store) List() ([]PublicRecord, error) {
|
||||
if s == nil {
|
||||
return nil, integrity(errors.New("uninitialized store"))
|
||||
}
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.listUnlocked()
|
||||
var records []PublicRecord
|
||||
err := s.withReaderLock(func() error {
|
||||
var listErr error
|
||||
records, listErr = s.listUnlocked()
|
||||
return listErr
|
||||
})
|
||||
return records, err
|
||||
}
|
||||
|
||||
func (s *Store) listUnlocked() ([]PublicRecord, error) {
|
||||
@@ -304,12 +310,7 @@ func (s *Store) revokeUnlocked(keyID, reason string, at time.Time) error {
|
||||
// Check validates every record and protected directory without exposing any
|
||||
// digest data.
|
||||
func (s *Store) Check() error {
|
||||
if s == nil {
|
||||
return integrity(errors.New("uninitialized store"))
|
||||
}
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.checkUnlocked()
|
||||
return s.withReaderLock(s.checkUnlocked)
|
||||
}
|
||||
|
||||
func (s *Store) checkUnlocked() error {
|
||||
@@ -320,6 +321,23 @@ func (s *Store) checkUnlocked() error {
|
||||
return validateLegacyMultiplicity(active, revoked)
|
||||
}
|
||||
|
||||
func (s *Store) withReaderLock(fn func() error) error {
|
||||
if s == nil {
|
||||
return integrity(errors.New("uninitialized store"))
|
||||
}
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
if s.root == nil || s.active == nil || s.revoked == nil {
|
||||
return integrity(errors.New("uninitialized store"))
|
||||
}
|
||||
lock, err := s.root.LockShared(registryLockName)
|
||||
if err != nil {
|
||||
return integrity(err)
|
||||
}
|
||||
defer lock.Close()
|
||||
return fn()
|
||||
}
|
||||
|
||||
func (s *Store) withWriterLock(fn func() error) error {
|
||||
if s == nil {
|
||||
return integrity(errors.New("uninitialized store"))
|
||||
@@ -329,7 +347,7 @@ func (s *Store) withWriterLock(fn func() error) error {
|
||||
if s.root == nil || s.active == nil || s.revoked == nil {
|
||||
return integrity(errors.New("uninitialized store"))
|
||||
}
|
||||
lock, err := s.root.Lock(".writer.lock")
|
||||
lock, err := s.root.Lock(registryLockName)
|
||||
if err != nil {
|
||||
return integrity(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user