20559: Garbage collect unused per-collection mutexes.
authorTom Clegg <tom@curii.com>
Wed, 14 Jun 2023 21:17:18 +0000 (17:17 -0400)
committerTom Clegg <tom@curii.com>
Thu, 29 Jun 2023 18:16:20 +0000 (14:16 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curii.com>

services/keep-web/handler.go
services/keep-web/handler_test.go

index e9b497a0b1165f5327bc74e7970f69d34318cf6e..4625602fc2c440bd52aac425fc0e9fdaed3fcea8 100644 (file)
@@ -37,8 +37,9 @@ type handler struct {
        Cluster   *arvados.Cluster
        setupOnce sync.Once
 
-       lockMtx sync.Mutex
-       lock    map[string]*sync.RWMutex
+       lockMtx    sync.Mutex
+       lock       map[string]*sync.RWMutex
+       lockTidied time.Time
 }
 
 var urlPDHDecoder = strings.NewReplacer(" ", "+", "-", "+")
@@ -958,6 +959,16 @@ var lockTidyInterval = time.Minute * 10
 func (h *handler) collectionLock(collectionID string, writing bool) sync.Locker {
        h.lockMtx.Lock()
        defer h.lockMtx.Unlock()
+       if time.Since(h.lockTidied) > lockTidyInterval {
+               // Periodically delete all locks that aren't in use.
+               h.lockTidied = time.Now()
+               for id, locker := range h.lock {
+                       if locker.TryLock() {
+                               locker.Unlock()
+                               delete(h.lock, id)
+                       }
+               }
+       }
        locker := h.lock[collectionID]
        if locker == nil {
                locker = new(sync.RWMutex)
index e7f8559c2451a3574f8f5dff745b556f9512b0ce..3b957c5a0da565b61d96a6ba13bbd2c3147ae897 100644 (file)
@@ -1627,6 +1627,7 @@ func (s *IntegrationSuite) TestUploadLoggingPermission(c *check.C) {
 }
 
 func (s *IntegrationSuite) TestConcurrentWrites(c *check.C) {
+       lockTidyInterval = time.Second
        client := arvados.NewClientFromEnv()
        client.AuthToken = arvadostest.ActiveTokenV2
        // Start small, and increase concurrency (2^2, 4^2, ...)