assistant: Avoid startup hang on active *.lock file

Avoid hanging at startup when a process has a *.lock file open in the .git
directory.

The goal is to repair stale locks, not wait for all active locks to be
closed. This was causing problems for a non-git process that has its own
lock file in a subdir of .git/.

If .git/index_lock is a non-stale lock, this does let the assistant start
up regardless. Commits by the assistant will then fail, until the process
locking the index finishes. This is not a problem, because the same
behavior could already happen if the assistant is started and then another
process locks the index.

Sponsored-by: the NIH-funded NICEMAN (ReproNim TR&D3) project
This commit is contained in:
Joey Hess 2025-05-22 12:56:31 -04:00
parent 47cf23785e
commit d7a28f21c9
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 32 additions and 13 deletions

View file

@ -147,17 +147,10 @@ repairStaleLocks lockfiles = go =<< getsizes
<$> getFileSize lf
getsizes = liftIO $ catMaybes <$> mapM getsize lockfiles
go [] = return ()
go l = ifM (liftIO $ null <$> Lsof.query ("--" : map (fromOsPath . fst) l))
( do
waitforit "to check stale git lock file"
l' <- getsizes
if l' == l
then liftIO $ mapM_ (removeWhenExistsWith removeFile . fst) l
else go l'
, do
waitforit "for git lock file writer"
go =<< getsizes
)
waitforit why = do
debug ["Waiting for 60 seconds", why]
go l = whenM (liftIO $ null <$> Lsof.query ("--" : map (fromOsPath . fst) l)) $ do
debug ["Waiting for 60 seconds to check stale git lock file"]
liftIO $ threadDelaySeconds $ Seconds 60
l' <- getsizes
if l' == l
then liftIO $ mapM_ (removeWhenExistsWith removeFile . fst) l
else go l'