Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMPROVED] Do not hold filestore lock during remove that needs to do IO. #4123

Merged
merged 1 commit into from May 2, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 22 additions & 2 deletions server/filestore.go
Expand Up @@ -2716,18 +2716,38 @@ func (fs *fileStore) removeMsg(seq uint64, secure, viaLimits, needFSLock bool) (
// Now just load regardless.
// TODO(dlc) - Figure out a way not to have to load it in, we need subject tracking outside main data block.
if mb.cacheNotLoaded() {
if err := mb.loadMsgsWithLock(); err != nil {
// We do not want to block possible activity within another msg block.
// We have to unlock both locks and acquire the mb lock in the loadMsgs() call to avoid a deadlock if another
// go routine was trying to get fs then this mb lock at the same time. E.g. another call to remove for same block.
mb.mu.Unlock()
fsUnlock()
if err := mb.loadMsgs(); err != nil {
return false, err
}
fsLock()
// We need to check if things changed out from underneath us.
if fs.closed {
fsUnlock()
return false, ErrStoreClosed
}
mb.mu.Lock()
if mb.closed || seq < mb.first.seq {
mb.mu.Unlock()
fsUnlock()
return false, err
return false, nil
}
// cacheLookup below will do dmap check so no need to repeat here.
}

var smv StoreMsg
sm, err := mb.cacheLookup(seq, &smv)
if err != nil {
mb.mu.Unlock()
fsUnlock()
// Mimic err behavior from above check to dmap. No error returned if already removed.
if err == errDeletedMsg {
err = nil
}
return false, err
}
// Grab size
Expand Down