watch for changes to transfer info files, to update progress bars on upload
This is handled differently for inotify, which can track modifications of existing files, and kqueue, which cannot (TTBOMK). On the inotify side, the TransferWatcher just waits for the file to be updated and reads the new bytesComplete. On the kqueue side, the TransferPoller has to re-read the file every update (currently 0.5 seconds, might need to increase that). I did think about working around kqueue's limitations by somehow creating a new file each time the size changed. But cleaning up all the files that would result seemed difficult. And really, this is not a lot worse than the TransferWatcher's behavior for downloads, which stats a file every 0.5 seconds. As long as the OS has decent file caching behavior..
This commit is contained in:
parent
06ed6ceac4
commit
68ad7de4d0
6 changed files with 63 additions and 11 deletions
|
@ -72,6 +72,20 @@ closingTracked = undefined
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* With inotify, modifications to existing files can be tracked.
|
||||
* Kqueue does not support this.
|
||||
*/
|
||||
modifyTracked :: Bool
|
||||
#if WITH_INOTIFY
|
||||
modifyTracked = True
|
||||
#else
|
||||
#if WITH_KQUEUE
|
||||
modifyTracked = False
|
||||
#else
|
||||
modifyTracked = undefined
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Starts a watcher thread. The runStartup action is passed a scanner action
|
||||
* to run, that will return once the initial directory scan is complete.
|
||||
* Once runStartup returns, the watcher thread continues running,
|
||||
|
|
|
@ -38,9 +38,8 @@ import Control.Exception (throw)
|
|||
- Note: Moving a file will cause events deleting it from its old location
|
||||
- and adding it to the new location.
|
||||
-
|
||||
- Note: Modification of files is not detected, and it's assumed that when
|
||||
- a file that was open for write is closed, it's finished being written
|
||||
- to, and can be added.
|
||||
- Note: It's assumed that when a file that was open for write is closed,
|
||||
- it's finished being written to, and can be added.
|
||||
-
|
||||
- Note: inotify has a limit to the number of watches allowed,
|
||||
- /proc/sys/fs/inotify/max_user_watches (default 8192).
|
||||
|
@ -66,13 +65,16 @@ watchDir i dir ignored hooks
|
|||
-- Select only inotify events required by the enabled
|
||||
-- hooks, but always include Create so new directories can
|
||||
-- be scanned.
|
||||
watchevents = Create : addevents ++ delevents
|
||||
watchevents = Create : addevents ++ delevents ++ modifyevents
|
||||
addevents
|
||||
| hashook addHook || hashook addSymlinkHook = [MoveIn, CloseWrite]
|
||||
| otherwise = []
|
||||
delevents
|
||||
| hashook delHook || hashook delDirHook = [MoveOut, Delete]
|
||||
| otherwise = []
|
||||
modifyevents
|
||||
| hashook modifyHook = [Modify]
|
||||
| otherwise = []
|
||||
|
||||
scan f = unless (ignored f) $ do
|
||||
ms <- getstatus f
|
||||
|
@ -114,6 +116,9 @@ watchDir i dir ignored hooks
|
|||
| otherwise = guarded $ runhook delHook f Nothing
|
||||
where
|
||||
guarded = unlessM (filetype (const True) f)
|
||||
go (Modified { isDirectory = isd, maybeFilePath = Just f })
|
||||
| isd = noop
|
||||
| otherwise = runhook modifyHook f Nothing
|
||||
go _ = noop
|
||||
|
||||
hashook h = isJust $ h hooks
|
||||
|
|
|
@ -19,7 +19,8 @@ data WatchHooks = WatchHooks
|
|||
, delHook :: Hook FilePath
|
||||
, delDirHook :: Hook FilePath
|
||||
, errHook :: Hook String -- error message
|
||||
, modifyHook :: Hook FilePath
|
||||
}
|
||||
|
||||
mkWatchHooks :: WatchHooks
|
||||
mkWatchHooks = WatchHooks Nothing Nothing Nothing Nothing Nothing
|
||||
mkWatchHooks = WatchHooks Nothing Nothing Nothing Nothing Nothing Nothing
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue