X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/5890e8edb97b50955dc37d94625649ad30473f42..1a2caf782dfd63a963094cd4b2bce5f5e7bfb7ef:/services/keep-web/handler.go diff --git a/services/keep-web/handler.go b/services/keep-web/handler.go index e9b497a0b1..3af326a1ad 100644 --- a/services/keep-web/handler.go +++ b/services/keep-web/handler.go @@ -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(" ", "+", "-", "+") @@ -410,16 +411,20 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) { // collection id is outside scope of supplied // token tokenScopeProblem = true + sess.Release() continue } else if os.IsNotExist(err) { // collection does not exist or is not // readable using this token + sess.Release() continue } else if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) + sess.Release() return } defer f.Close() + defer sess.Release() collectionDir, sessionFS, session, tokenUser = f, fs, sess, user break @@ -958,6 +963,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)