clean up unused locks

This commit is contained in:
Evan Jarrett
2025-12-26 09:48:25 -06:00
parent 363c12e6bf
commit 24d6b49481
2 changed files with 12 additions and 44 deletions
+2 -18
View File
@@ -10,7 +10,6 @@ import (
"log/slog"
"net/http"
"strings"
"sync"
"time"
"atcr.io/pkg/appview/readme"
@@ -22,10 +21,8 @@ import (
// ManifestStore implements distribution.ManifestService
// It stores manifests in ATProto as records
type ManifestStore struct {
ctx *RegistryContext // Context with user/hold info
mu sync.RWMutex // Protects lastFetchedHoldDID
lastFetchedHoldDID string // Hold DID from most recently fetched manifest (for pull)
blobStore distribution.BlobStore // Blob store for fetching config during push
ctx *RegistryContext // Context with user/hold info
blobStore distribution.BlobStore // Blob store for fetching config during push
}
// NewManifestStore creates a new ATProto-backed manifest store
@@ -66,19 +63,6 @@ func (s *ManifestStore) Get(ctx context.Context, dgst digest.Digest, options ...
return nil, fmt.Errorf("failed to unmarshal manifest record: %w", err)
}
// Store the hold DID for subsequent blob requests during pull
// Prefer HoldDID (new format) with fallback to HoldEndpoint (legacy URL format)
// The routing repository will cache this for concurrent blob fetches
s.mu.Lock()
if manifestRecord.HoldDID != "" {
// New format: DID reference (preferred)
s.lastFetchedHoldDID = manifestRecord.HoldDID
} else if manifestRecord.HoldEndpoint != "" {
// Legacy format: URL reference - convert to DID
s.lastFetchedHoldDID = atproto.ResolveHoldDIDFromURL(manifestRecord.HoldEndpoint)
}
s.mu.Unlock()
var ociManifest []byte
// New records: Download blob from ATProto blob storage
+10 -26
View File
@@ -7,19 +7,19 @@ package storage
import (
"context"
"log/slog"
"sync"
"github.com/distribution/distribution/v3"
)
// RoutingRepository routes manifests to ATProto and blobs to external hold service
// The registry (AppView) is stateless and NEVER stores blobs locally
// NOTE: A fresh instance is created per-request (see middleware/registry.go)
// so no mutex is needed - each request has its own instance
type RoutingRepository struct {
distribution.Repository
Ctx *RegistryContext // All context and services (exported for token updates)
mu sync.Mutex // Protects manifestStore and blobStore
manifestStore *ManifestStore // Cached manifest store instance
blobStore *ProxyBlobStore // Cached blob store instance
manifestStore *ManifestStore // Manifest store instance (lazy-initialized)
blobStore *ProxyBlobStore // Blob store instance (lazy-initialized)
}
// NewRoutingRepository creates a new routing repository
@@ -32,36 +32,22 @@ func NewRoutingRepository(baseRepo distribution.Repository, ctx *RegistryContext
// Manifests returns the ATProto-backed manifest service
func (r *RoutingRepository) Manifests(ctx context.Context, options ...distribution.ManifestServiceOption) (distribution.ManifestService, error) {
r.mu.Lock()
// Create or return cached manifest store
// Lazy-initialize manifest store (no mutex needed - one instance per request)
if r.manifestStore == nil {
// Ensure blob store is created first (needed for label extraction during push)
// Release lock while calling Blobs to avoid deadlock
r.mu.Unlock()
blobStore := r.Blobs(ctx)
r.mu.Lock()
// Double-check after reacquiring lock (another goroutine might have set it)
if r.manifestStore == nil {
r.manifestStore = NewManifestStore(r.Ctx, blobStore)
}
r.manifestStore = NewManifestStore(r.Ctx, blobStore)
}
manifestStore := r.manifestStore
r.mu.Unlock()
return manifestStore, nil
return r.manifestStore, nil
}
// Blobs returns a proxy blob store that routes to external hold service
// The registry (AppView) NEVER stores blobs locally - all blobs go through hold service
func (r *RoutingRepository) Blobs(ctx context.Context) distribution.BlobStore {
r.mu.Lock()
// Return cached blob store if available
// Return cached blob store if available (no mutex needed - one instance per request)
if r.blobStore != nil {
blobStore := r.blobStore
r.mu.Unlock()
slog.Debug("Returning cached blob store", "component", "storage/blobs", "did", r.Ctx.DID, "repo", r.Ctx.Repository)
return blobStore
return r.blobStore
}
// Determine if this is a pull (GET/HEAD) or push (PUT/POST/etc) operation
@@ -103,9 +89,7 @@ func (r *RoutingRepository) Blobs(ctx context.Context) distribution.BlobStore {
// Create and cache proxy blob store
r.blobStore = NewProxyBlobStore(r.Ctx)
blobStore := r.blobStore
r.mu.Unlock()
return blobStore
return r.blobStore
}
// Tags returns the tag service