race avoidance
When there are duplicate add events for the same file, only add it once.
This commit is contained in:
parent
96ac25094b
commit
7ee300a47f
1 changed files with 45 additions and 35 deletions
|
@ -76,41 +76,6 @@ commitThread st changechan = runEvery (Seconds 1) $ do
|
||||||
void $ tryIO $ runThreadState st commitStaged
|
void $ tryIO $ runThreadState st commitStaged
|
||||||
else refillChanges changechan cs
|
else refillChanges changechan cs
|
||||||
|
|
||||||
{- If there are PendingAddChanges, the files have not yet actually been
|
|
||||||
- added to the annex, and that has to be done now, before committing.
|
|
||||||
-
|
|
||||||
- Deferring the adds to this point causes batches to be bundled together,
|
|
||||||
- which allows faster checking with lsof that the files are not still open
|
|
||||||
- for write by some other process.
|
|
||||||
-
|
|
||||||
- When a file is added, Inotify will notice the new symlink. So this waits
|
|
||||||
- for additional Changes to arrive, so that the symlink has hopefully been
|
|
||||||
- staged before returning.
|
|
||||||
-}
|
|
||||||
handleAdds :: ThreadState -> ChangeChan -> [Change] -> IO ()
|
|
||||||
handleAdds st changechan cs
|
|
||||||
| null added = noop
|
|
||||||
| otherwise = do
|
|
||||||
forM_ added $ catchBoolIO . runThreadState st . add
|
|
||||||
handleAdds st changechan =<< getChanges changechan
|
|
||||||
where
|
|
||||||
added = map changeFile $ filter isPendingAdd cs
|
|
||||||
|
|
||||||
isPendingAdd (Change { changeType = PendingAddChange }) = True
|
|
||||||
isPendingAdd _ = False
|
|
||||||
|
|
||||||
add file = do
|
|
||||||
showStart "add" file
|
|
||||||
handle file =<< Command.Add.ingest file
|
|
||||||
|
|
||||||
handle _ Nothing = do
|
|
||||||
showEndFail
|
|
||||||
return False
|
|
||||||
handle file (Just key) = do
|
|
||||||
Command.Add.link file key True
|
|
||||||
showEndOk
|
|
||||||
return True
|
|
||||||
|
|
||||||
commitStaged :: Annex ()
|
commitStaged :: Annex ()
|
||||||
commitStaged = do
|
commitStaged = do
|
||||||
Annex.Queue.flush
|
Annex.Queue.flush
|
||||||
|
@ -141,3 +106,48 @@ shouldCommit now changes
|
||||||
where
|
where
|
||||||
len = length changes
|
len = length changes
|
||||||
thisSecond c = now `diffUTCTime` changeTime c <= 1
|
thisSecond c = now `diffUTCTime` changeTime c <= 1
|
||||||
|
|
||||||
|
{- If there are PendingAddChanges, the files have not yet actually been
|
||||||
|
- added to the annex (probably), and that has to be done now, before
|
||||||
|
- committing.
|
||||||
|
-
|
||||||
|
- Deferring the adds to this point causes batches to be bundled together,
|
||||||
|
- which allows faster checking with lsof that the files are not still open
|
||||||
|
- for write by some other process.
|
||||||
|
-
|
||||||
|
- When a file is added, Inotify will notice the new symlink. So this waits
|
||||||
|
- for additional Changes to arrive, so that the symlink has hopefully been
|
||||||
|
- staged before returning, and will be committed.
|
||||||
|
-}
|
||||||
|
handleAdds :: ThreadState -> ChangeChan -> [Change] -> IO ()
|
||||||
|
handleAdds st changechan cs
|
||||||
|
| null toadd = noop
|
||||||
|
| otherwise = do
|
||||||
|
added <- filter id <$> forM toadd go
|
||||||
|
unless (null added) $
|
||||||
|
handleAdds st changechan =<< getChanges changechan
|
||||||
|
where
|
||||||
|
toadd = map changeFile $ filter isPendingAdd cs
|
||||||
|
|
||||||
|
isPendingAdd (Change { changeType = PendingAddChange }) = True
|
||||||
|
isPendingAdd _ = False
|
||||||
|
|
||||||
|
go file = do
|
||||||
|
ms <- catchMaybeIO $ getSymbolicLinkStatus file
|
||||||
|
case ms of
|
||||||
|
Just s
|
||||||
|
| isRegularFile s -> catchBoolIO $
|
||||||
|
runThreadState st $ add file
|
||||||
|
_ -> return False
|
||||||
|
|
||||||
|
add file = do
|
||||||
|
showStart "add" file
|
||||||
|
handle file =<< Command.Add.ingest file
|
||||||
|
|
||||||
|
handle _ Nothing = do
|
||||||
|
showEndFail
|
||||||
|
return False
|
||||||
|
handle file (Just key) = do
|
||||||
|
Command.Add.link file key True
|
||||||
|
showEndOk
|
||||||
|
return True
|
||||||
|
|
Loading…
Add table
Reference in a new issue