on master help sign in
Fix #1332 and change default config

fixes #1332 Changes default config to use non-recursive watch as recursive watch has some issues on Linux and therefore not included in the common module.

commit0869165680cca8e6b6cbf28ba6cbea80d216ba8e authorHarendra Kumar <harendra@composewell.com> dateSat 13 Nov 2021, 23:57 (5 years ago) parent4512fa4
1 file changed+34−16
src/Streamly/Internal/FileSystem/Event/Linux.hs+34−16
src/Streamly/Internal/FileSystem/Event/Linux.hs+34−16
@@ -220,7 +220,7 @@ data Config = Config
220220--
221221-- /Pre-release/
222222--
223−data Toggle = On | Off
223+data Toggle = On | Off deriving (Show, Eq)
224224
225225toggle :: Toggle -> Toggle
226226toggle On = Off
@@ -245,8 +245,8 @@ setFlag mask status cfg@Config{..} =
245245--
246246-- /Pre-release/
247247--
248−setRecursiveMode :: Bool -> Config -> Config
249−setRecursiveMode rec cfg@Config{} = cfg {watchRec = rec}
248+setRecursiveMode :: Toggle -> Config -> Config
249+setRecursiveMode rec cfg@Config{} = cfg {watchRec = rec == On}
250250
251251foreign import capi
252252 "sys/inotify.h value IN_DONT_FOLLOW" iN_DONT_FOLLOW :: Word32
@@ -562,7 +562,7 @@ defaultConfig =
562562 $ setMovedTo On
563563 $ setModified On
564564 $ Config
565− { watchRec = True
565+ { watchRec = False
566566 , createFlags = 0
567567 }
568568
@@ -682,6 +682,12 @@ removeTrailingSlash path =
682682 else path
683683 else path
684684
685+appendPaths :: Array Word8 -> Array Word8 -> Array Word8
686+appendPaths a b
687+ | byteLength a == 0 = b
688+ | byteLength b == 0 = a
689+ | otherwise = ensureTrailingSlash a <> b
690+
685691-- | @addToWatch cfg watch root subpath@ adds @subpath@ to the list of paths
686692-- being monitored under @root@ via the watch handle @watch@. @root@ must be
687693-- an absolute path and @subpath@ must be relative to @root@.
@@ -708,9 +714,11 @@ addToWatch cfg@Config{..} watch0@(Watch handle wdMap) root0 path0 = do
708714 -- handle it. For example, if it is a dir create the application can read
709715 -- the dir to scan the files in it.
710716 --
711− let root = ensureTrailingSlash root0
712− path = ensureTrailingSlash path0
713− absPath = root <> path
717+ let root = removeTrailingSlash root0
718+ path = removeTrailingSlash path0
719+ absPath = appendPaths root path
720+ putStrLn $ "root = " ++ utf8ToString root ++ " path = " ++ utf8ToString path ++ " absPath = " ++ utf8ToString absPath
721+
714722 fd <- handleToFd handle
715723
716724 -- XXX we need to tolerate an error where we are adding a watch for a
@@ -733,12 +741,12 @@ addToWatch cfg@Config{..} watch0@(Watch handle wdMap) root0 path0 = do
733741 -- parent, this will make sure they are added too.
734742 --
735743 -- XXX Ensure that we generate events that we may have missed while we were
736− -- adding the dirs.
744+ -- adding the dirs. That may generate spurious events though.
737745 --
738746 -- XXX toDirs currently uses paths as String, we need to convert it
739747 -- to "/" separated by byte arrays.
740748 when watchRec $ do
741− S.mapM_ (\p -> addToWatch cfg watch0 root (path <> p))
749+ S.mapM_ (\p -> addToWatch cfg watch0 root (appendPaths path p))
742750 $ S.mapM toUtf8
743751 $ Dir.toDirs $ utf8ToString absPath
744752
@@ -779,7 +787,9 @@ removeFromWatch (Watch handle wdMap) path = do
779787openWatch :: Config -> NonEmpty (Array Word8) -> IO Watch
780788openWatch cfg paths = do
781789 w <- createWatch
782− mapM_ (\p -> addToWatch cfg w p (A.fromList [])) $ NonEmpty.toList paths
790+ mapM_
791+ (\root -> addToWatch cfg w root (A.fromList []))
792+ $ NonEmpty.toList paths
783793 return w
784794
785795-- | Close a 'Watch' handle.
@@ -852,8 +862,7 @@ readOneEvent cfg wt@(Watch _ wdMap) = do
852862 error $ "readOneEvent: "
853863 <> "Unknown watch descriptor: "
854864 <> show ewd
855− let -- "sub" is guaranteed to have a trailing "/"
856− sub1 = sub <> path
865+ let sub1 = appendPaths sub path
857866 -- Check for "ISDIR" first because it is less likely
858867 isDirCreate = eflags .&. iN_ISDIR /= 0 && eflags .&. iN_CREATE /= 0
859868 when (watchRec cfg && isDirCreate)
@@ -941,23 +950,23 @@ watchWith f paths = S.bracket before after (watchToStream cfg)
941950
942951-- | Same as 'watchWith' using 'defaultConfig' and recursive mode.
943952--
944−-- >>> watchRecursive = watchWith id
953+-- >>> watchRecursive = watchWith (setRecursiveMode On)
945954--
946955-- See 'watchWith' for pitfalls and bugs when using recursive watch on Linux.
947956--
948957-- /Pre-release/
949958--
950959watchRecursive :: NonEmpty (Array Word8) -> SerialT IO Event
951−watchRecursive = watchWith id
960+watchRecursive = watchWith (setRecursiveMode On)
952961
953962-- | Same as 'watchWith' using defaultConfig and non-recursive mode.
954963--
955−-- >>> watch = watchWith (setRecursiveMode False)
964+-- >>> watch = watchWith id
956965--
957966-- /Pre-release/
958967--
959968watch :: NonEmpty (Array Word8) -> SerialT IO Event
960−watch = watchWith (setRecursiveMode False)
969+watch = watchWith id
961970
962971-------------------------------------------------------------------------------
963972-- Examine event stream
@@ -1057,6 +1066,9 @@ foreign import capi
10571066-- | A path was removed from the watch explicitly using 'removeFromWatch' or
10581067-- automatically (file was deleted, or filesystem was unmounted).
10591068--
1069+-- Note that in recursive watch mode all the subdirectories are watch roots,
1070+-- therefore, they will all generate this event.
1071+--
10601072-- /Occurs only for a watched path/
10611073--
10621074-- /Pre-release/
@@ -1070,6 +1082,9 @@ isRootUnwatched = getFlag iN_IGNORED
10701082-- In addition, an 'isRootUnwatched' event will subsequently be generated
10711083-- for the watch descriptor.
10721084--
1085+-- Note that in recursive watch mode all the subdirectories are watch roots,
1086+-- therefore, they will all generate this event.
1087+--
10731088-- /Occurs only for a watched path/
10741089--
10751090-- /Pre-release/
@@ -1079,6 +1094,9 @@ isRootDeleted = getFlag iN_DELETE_SELF
10791094
10801095-- | Watched file/directory was itself moved within the file system.
10811096--
1097+-- Note that in recursive watch mode all the subdirectories are watch roots,
1098+-- therefore, they will all generate this event.
1099+--
10821100-- /Occurs only for a watched path/
10831101--
10841102-- /Pre-release/