@@ -10,7 +10,6 @@ import (
10
10
"path"
11
11
"path/filepath"
12
12
"strings"
13
- "sync"
14
13
"time"
15
14
"unicode/utf8"
16
15
@@ -42,7 +41,7 @@ const (
42
41
type ImageStore struct {
43
42
rootDir string
44
43
storeDriver storageTypes.Driver
45
- lock * sync. RWMutex
44
+ lock * ImageStoreLock
46
45
log zlog.Logger
47
46
metrics monitoring.MetricServer
48
47
cache cache.Cache
@@ -78,7 +77,7 @@ func NewImageStore(rootDir string, cacheDir string, dedupe, commit bool, log zlo
78
77
imgStore := & ImageStore {
79
78
rootDir : rootDir ,
80
79
storeDriver : storeDriver ,
81
- lock : & sync. RWMutex {} ,
80
+ lock : NewImageStoreLock () ,
82
81
log : log ,
83
82
metrics : metrics ,
84
83
dedupe : dedupe ,
@@ -124,6 +123,40 @@ func (is *ImageStore) Unlock(lockStart *time.Time) {
124
123
monitoring .ObserveStorageLockLatency (is .metrics , latency , is .RootDir (), storageConstants .RWLOCK ) // histogram
125
124
}
126
125
126
+ // RLock read-lock for specific repo
127
+ func (is * ImageStore ) RLockRepo (repo string , lockStart * time.Time ) {
128
+ * lockStart = time .Now ()
129
+
130
+ is .lock .RLockRepo (repo )
131
+ }
132
+
133
+ // RUnlock read-unlock for specific repo.
134
+ func (is * ImageStore ) RUnlockRepo (repo string , lockStart * time.Time ) {
135
+ is .lock .RUnlockRepo (repo )
136
+
137
+ lockEnd := time .Now ()
138
+ // includes time spent in acquiring and holding a lock
139
+ latency := lockEnd .Sub (* lockStart )
140
+ monitoring .ObserveStorageLockLatency (is .metrics , latency , is .RootDir (), storageConstants .RLOCK ) // histogram
141
+ }
142
+
143
+ // Lock write-lock for specific repo..
144
+ func (is * ImageStore ) LockRepo (repo string , lockStart * time.Time ) {
145
+ * lockStart = time .Now ()
146
+
147
+ is .lock .LockRepo (repo )
148
+ }
149
+
150
+ // Unlock write-unlock for specific repo..
151
+ func (is * ImageStore ) UnlockRepo (repo string , lockStart * time.Time ) {
152
+ is .lock .UnlockRepo (repo )
153
+
154
+ lockEnd := time .Now ()
155
+ // includes time spent in acquiring and holding a lock
156
+ latency := lockEnd .Sub (* lockStart )
157
+ monitoring .ObserveStorageLockLatency (is .metrics , latency , is .RootDir (), storageConstants .RWLOCK ) // histogram
158
+ }
159
+
127
160
func (is * ImageStore ) initRepo (name string ) error {
128
161
repoDir := path .Join (is .rootDir , name )
129
162
@@ -200,8 +233,8 @@ func (is *ImageStore) initRepo(name string) error {
200
233
func (is * ImageStore ) InitRepo (name string ) error {
201
234
var lockLatency time.Time
202
235
203
- is .Lock ( & lockLatency )
204
- defer is .Unlock ( & lockLatency )
236
+ is .LockRepo ( name , & lockLatency )
237
+ defer is .UnlockRepo ( name , & lockLatency )
205
238
206
239
return is .initRepo (name )
207
240
}
@@ -392,8 +425,8 @@ func (is *ImageStore) GetImageTags(repo string) ([]string, error) {
392
425
return nil , zerr .ErrRepoNotFound
393
426
}
394
427
395
- is .RLock ( & lockLatency )
396
- defer is .RUnlock ( & lockLatency )
428
+ is .RLockRepo ( repo , & lockLatency )
429
+ defer is .RUnlockRepo ( repo , & lockLatency )
397
430
398
431
index , err := common .GetIndex (is , repo , is .log )
399
432
if err != nil {
@@ -414,9 +447,9 @@ func (is *ImageStore) GetImageManifest(repo, reference string) ([]byte, godigest
414
447
415
448
var err error
416
449
417
- is .RLock ( & lockLatency )
450
+ is .RLockRepo ( repo , & lockLatency )
418
451
defer func () {
419
- is .RUnlock ( & lockLatency )
452
+ is .RUnlockRepo ( repo , & lockLatency )
420
453
421
454
if err == nil {
422
455
monitoring .IncDownloadCounter (is .metrics , repo )
@@ -466,9 +499,9 @@ func (is *ImageStore) PutImageManifest(repo, reference, mediaType string, //noli
466
499
467
500
var err error
468
501
469
- is .Lock ( & lockLatency )
502
+ is .LockRepo ( repo , & lockLatency )
470
503
defer func () {
471
- is .Unlock ( & lockLatency )
504
+ is .UnlockRepo ( repo , & lockLatency )
472
505
473
506
if err == nil {
474
507
if is .storeDriver .Name () == storageConstants .LocalStorageDriverName {
@@ -596,8 +629,8 @@ func (is *ImageStore) DeleteImageManifest(repo, reference string, detectCollisio
596
629
597
630
var lockLatency time.Time
598
631
599
- is .Lock ( & lockLatency )
600
- defer is .Unlock ( & lockLatency )
632
+ is .LockRepo ( repo , & lockLatency )
633
+ defer is .UnlockRepo ( repo , & lockLatency )
601
634
602
635
err := is .deleteImageManifest (repo , reference , detectCollisions )
603
636
if err != nil {
@@ -885,8 +918,8 @@ func (is *ImageStore) FinishBlobUpload(repo, uuid string, body io.Reader, dstDig
885
918
886
919
var lockLatency time.Time
887
920
888
- is .Lock ( & lockLatency )
889
- defer is .Unlock ( & lockLatency )
921
+ is .LockRepo ( repo , & lockLatency )
922
+ defer is .UnlockRepo ( repo , & lockLatency )
890
923
891
924
if is .dedupe && fmt .Sprintf ("%v" , is .cache ) != fmt .Sprintf ("%v" , nil ) {
892
925
err = is .DedupeBlob (src , dstDigest , repo , dst )
@@ -965,8 +998,8 @@ func (is *ImageStore) FullBlobUpload(repo string, body io.Reader, dstDigest godi
965
998
966
999
var lockLatency time.Time
967
1000
968
- is .Lock ( & lockLatency )
969
- defer is .Unlock ( & lockLatency )
1001
+ is .LockRepo ( repo , & lockLatency )
1002
+ defer is .UnlockRepo ( repo , & lockLatency )
970
1003
971
1004
dst := is .BlobPath (repo , dstDigest )
972
1005
@@ -1168,11 +1201,11 @@ func (is *ImageStore) CheckBlob(repo string, digest godigest.Digest) (bool, int6
1168
1201
blobPath := is .BlobPath (repo , digest )
1169
1202
1170
1203
if is .dedupe && fmt .Sprintf ("%v" , is .cache ) != fmt .Sprintf ("%v" , nil ) {
1171
- is .Lock ( & lockLatency )
1172
- defer is .Unlock ( & lockLatency )
1204
+ is .LockRepo ( repo , & lockLatency )
1205
+ defer is .UnlockRepo ( repo , & lockLatency )
1173
1206
} else {
1174
- is .RLock ( & lockLatency )
1175
- defer is .RUnlock ( & lockLatency )
1207
+ is .RLockRepo ( repo , & lockLatency )
1208
+ defer is .RUnlockRepo ( repo , & lockLatency )
1176
1209
}
1177
1210
1178
1211
binfo , err := is .storeDriver .Stat (blobPath )
@@ -1304,8 +1337,8 @@ func (is *ImageStore) GetBlobPartial(repo string, digest godigest.Digest, mediaT
1304
1337
return nil , - 1 , - 1 , err
1305
1338
}
1306
1339
1307
- is .RLock ( & lockLatency )
1308
- defer is .RUnlock ( & lockLatency )
1340
+ is .RLockRepo ( repo , & lockLatency )
1341
+ defer is .RUnlockRepo ( repo , & lockLatency )
1309
1342
1310
1343
binfo , err := is .originalBlobInfo (repo , digest )
1311
1344
if err != nil {
@@ -1381,8 +1414,8 @@ func (is *ImageStore) GetBlob(repo string, digest godigest.Digest, mediaType str
1381
1414
return nil , - 1 , err
1382
1415
}
1383
1416
1384
- is .RLock ( & lockLatency )
1385
- defer is .RUnlock ( & lockLatency )
1417
+ is .LockRepo ( repo , & lockLatency )
1418
+ defer is .UnlockRepo ( repo , & lockLatency )
1386
1419
1387
1420
binfo , err := is .originalBlobInfo (repo , digest )
1388
1421
if err != nil {
@@ -1458,8 +1491,8 @@ func (is *ImageStore) GetReferrers(repo string, gdigest godigest.Digest, artifac
1458
1491
) (ispec.Index , error ) {
1459
1492
var lockLatency time.Time
1460
1493
1461
- is .RLock ( & lockLatency )
1462
- defer is .RUnlock ( & lockLatency )
1494
+ is .RLockRepo ( repo , & lockLatency )
1495
+ defer is .RUnlockRepo ( repo , & lockLatency )
1463
1496
1464
1497
return common .GetReferrers (is , repo , gdigest , artifactTypes , is .log )
1465
1498
}
@@ -1532,8 +1565,8 @@ func (is *ImageStore) DeleteBlob(repo string, digest godigest.Digest) error {
1532
1565
return err
1533
1566
}
1534
1567
1535
- is .Lock ( & lockLatency )
1536
- defer is .Unlock ( & lockLatency )
1568
+ is .LockRepo ( repo , & lockLatency )
1569
+ defer is .UnlockRepo ( repo , & lockLatency )
1537
1570
1538
1571
return is .deleteBlob (repo , digest )
1539
1572
}
0 commit comments