github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/registry/storage/cache/cachedblobdescriptorstore.go (about) 1 package cache 2 3 import ( 4 "github.com/docker/distribution/context" 5 "github.com/docker/distribution/digest" 6 7 "github.com/docker/distribution" 8 ) 9 10 // Metrics is used to hold metric counters 11 // related to the number of times a cache was 12 // hit or missed. 13 type Metrics struct { 14 Requests uint64 15 Hits uint64 16 Misses uint64 17 } 18 19 // MetricsTracker represents a metric tracker 20 // which simply counts the number of hits and misses. 21 type MetricsTracker interface { 22 Hit() 23 Miss() 24 Metrics() Metrics 25 } 26 27 type cachedBlobStatter struct { 28 cache distribution.BlobDescriptorService 29 backend distribution.BlobDescriptorService 30 tracker MetricsTracker 31 } 32 33 // NewCachedBlobStatter creates a new statter which prefers a cache and 34 // falls back to a backend. 35 func NewCachedBlobStatter(cache distribution.BlobDescriptorService, backend distribution.BlobDescriptorService) distribution.BlobDescriptorService { 36 return &cachedBlobStatter{ 37 cache: cache, 38 backend: backend, 39 } 40 } 41 42 // NewCachedBlobStatterWithMetrics creates a new statter which prefers a cache and 43 // falls back to a backend. Hits and misses will send to the tracker. 44 func NewCachedBlobStatterWithMetrics(cache distribution.BlobDescriptorService, backend distribution.BlobDescriptorService, tracker MetricsTracker) distribution.BlobStatter { 45 return &cachedBlobStatter{ 46 cache: cache, 47 backend: backend, 48 tracker: tracker, 49 } 50 } 51 52 func (cbds *cachedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { 53 desc, err := cbds.cache.Stat(ctx, dgst) 54 if err != nil { 55 if err != distribution.ErrBlobUnknown { 56 context.GetLogger(ctx).Errorf("error retrieving descriptor from cache: %v", err) 57 } 58 59 goto fallback 60 } 61 62 if cbds.tracker != nil { 63 cbds.tracker.Hit() 64 } 65 return desc, nil 66 fallback: 67 if cbds.tracker != nil { 68 cbds.tracker.Miss() 69 } 70 desc, err = cbds.backend.Stat(ctx, dgst) 71 if err != nil { 72 return desc, err 73 } 74 75 if err := cbds.cache.SetDescriptor(ctx, dgst, desc); err != nil { 76 context.GetLogger(ctx).Errorf("error adding descriptor %v to cache: %v", desc.Digest, err) 77 } 78 79 return desc, err 80 81 } 82 83 func (cbds *cachedBlobStatter) Clear(ctx context.Context, dgst digest.Digest) error { 84 err := cbds.cache.Clear(ctx, dgst) 85 if err != nil { 86 return err 87 } 88 89 err = cbds.backend.Clear(ctx, dgst) 90 if err != nil { 91 return err 92 } 93 return nil 94 } 95 96 func (cbds *cachedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error { 97 if err := cbds.cache.SetDescriptor(ctx, dgst, desc); err != nil { 98 context.GetLogger(ctx).Errorf("error adding descriptor %v to cache: %v", desc.Digest, err) 99 } 100 return nil 101 }