Skip to content

Commit 6c21319

Browse files
committed
storage: limit number of goroutines used in moveCachedSerialsToStorage
1 parent 129f7e3 commit 6c21319

File tree

2 files changed

+55
-19
lines changed

2 files changed

+55
-19
lines changed

go/storage/certdatabase.go

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import (
2323
)
2424

2525
const (
26-
permModeDir = 0755
26+
permModeDir = 0755
27+
kMoveSerialsBatchSize = 1000
2728
)
2829

2930
func serialListExpiryLine(aExpDate types.ExpDate) string {
@@ -456,24 +457,27 @@ func (db *CertDatabase) moveCachedSerialsToStorage() error {
456457
if err != nil {
457458
return err
458459
}
459-
// We'll process the expiry shards in parallel. There are only a
460-
// few thousand shards per issuer, and goroutines are cheap, so
461-
// we don't need to worry about spinning up too many workers.
462-
glog.Infof("[%s] Moving %d expiry bins to storage.", issuer.ID(), len(issuerDate.ExpDates))
463-
errChan := make(chan error, len(issuerDate.ExpDates))
464-
var wg sync.WaitGroup
465-
wg.Add(len(issuerDate.ExpDates))
466-
for _, expDate := range issuerDate.ExpDates {
467-
go func(expDate types.ExpDate) {
468-
errChan <- db.moveOneBinOfCachedSerialsToStorage(tmpDir, expDate, issuer)
469-
wg.Done()
470-
}(expDate)
471-
}
472-
wg.Wait()
473-
close(errChan)
474-
for err := range errChan {
475-
if err != nil {
476-
return err
460+
batchSize := kMoveSerialsBatchSize
461+
for start := 0; start < len(issuerDate.ExpDates); start += batchSize {
462+
if start+batchSize > len(issuerDate.ExpDates) {
463+
batchSize = len(issuerDate.ExpDates) - start
464+
}
465+
glog.Infof("[%s] Moving %d expiry bins to storage.", issuer.ID(), batchSize)
466+
errChan := make(chan error, batchSize)
467+
var wg sync.WaitGroup
468+
wg.Add(batchSize)
469+
for i := start; i < start+batchSize; i++ {
470+
go func(expDate types.ExpDate) {
471+
errChan <- db.moveOneBinOfCachedSerialsToStorage(tmpDir, expDate, issuer)
472+
wg.Done()
473+
}(issuerDate.ExpDates[i])
474+
}
475+
wg.Wait()
476+
close(errChan)
477+
for err := range errChan {
478+
if err != nil {
479+
return err
480+
}
477481
}
478482
}
479483
}

go/storage/certdatabase_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,38 @@ func Test_MoveCachedSerialsToStorageIdempotent(t *testing.T) {
394394
expectCountStored(t, certDB, kDate1, kIssuer1, "01", 1)
395395
}
396396

397+
func Test_MoveManyCachedSerialsToStorage(t *testing.T) {
398+
_, certDB := getTestHarness(t)
399+
400+
expiryBase, _ := time.Parse(kExpirationFormat, "2050-01-01")
401+
402+
// Add a large number of cache entries with distinct expiry dates.
403+
// This will exercise the batching behavior in moveCachedSerialsToStorage.
404+
count := kMoveSerialsBatchSize + 17
405+
for i := 0; i < count; i++ {
406+
expiry := expiryBase.Add(time.Duration(i*24) * time.Hour)
407+
cacheSerial(t, certDB, expiry.Format(kExpirationFormat), kIssuer1, "01")
408+
}
409+
410+
err := certDB.moveCachedSerialsToStorage()
411+
if err != nil {
412+
t.Errorf("Could not move cached serials to storage: %s", err)
413+
}
414+
415+
// Check the end points of the batches
416+
expiry := expiryBase.Add((0 * 24) * time.Hour)
417+
expectStored(t, certDB, expiry.Format(kExpirationFormat), kIssuer1, "01", true)
418+
419+
expiry = expiryBase.Add(((kMoveSerialsBatchSize - 1) * 24) * time.Hour)
420+
expectStored(t, certDB, expiry.Format(kExpirationFormat), kIssuer1, "01", true)
421+
422+
expiry = expiryBase.Add((kMoveSerialsBatchSize * 24) * time.Hour)
423+
expectStored(t, certDB, expiry.Format(kExpirationFormat), kIssuer1, "01", true)
424+
425+
expiry = expiryBase.Add((kMoveSerialsBatchSize + 16) * 24 * time.Hour)
426+
expectStored(t, certDB, expiry.Format(kExpirationFormat), kIssuer1, "01", true)
427+
}
428+
397429
func Test_Commit(t *testing.T) {
398430
cache, certDB := getTestHarness(t)
399431

0 commit comments

Comments
 (0)