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

Ability to wait for inotify threads #34

Open
viviag opened this issue Aug 2, 2021 · 2 comments
Open

Ability to wait for inotify threads #34

viviag opened this issue Aug 2, 2021 · 2 comments

Comments

@viviag
Copy link

viviag commented Aug 2, 2021

I'm implementing a daemon process. It inits inotify and must persist while inotify threads persist.

Do you consider some API change allowing to wait for inotify threads?
As a simpler alternative it may be enough to export INotify constructor, I did it in a fork and may submit as a PR.

@kolmodin
Copy link
Collaborator

kolmodin commented Aug 5, 2021

Hi,

can you share a snippet of your use case?

If you intend the daemon process to stop when inotify is done, maybe you can use withINotify?

daemon = withInotify $ \ inot -> do
  ...

Or just end the daemon with killINotify which will wait until the inotify threads are done.

@viviag
Copy link
Author

viviag commented Aug 5, 2021

Sure.

What I want to do is closest to run1 function in the snippet -- in main thread I want to add inotify watch, execute some set of actions concurrently and stay alive forever. Handler of Events spawns thread executing same action.
Actually start monitors for all directories in watched directory, but keep watch to start monitors for newly created directories.

In the snippet this action is represented by actionInternals. But real action can terminate if subdirectory it is watching is deleted.
To represent this behaviour in run2, run3 and run4 I removed this action -- practically interesting cases are there actionInternals terminates in finite time.

After reading your comment I tried to use withINotify or killINotify here. But run3 and run4 terminated immediately with no output in repl and didn't react to file changes. So it does not help.

run2 works as required. It does not terminate and reacts to events.

run5 works as needed in GHCi, but do not work if compiled -- main thread is that of program, not of interpreter.

{-# LANGUAGE OverloadedStrings #-}
module Waiting where

import System.INotify
import Control.Concurrent
import Control.Concurrent.Async
import Control.Monad

-- Some dull eternal action
action :: String -> Event -> IO ()
action msg _ = actionInternals msg

actionInternals :: String -> IO ()
actionInternals msg = forever $ do
  putStrLn msg
  threadDelay 10000000

run1 :: IO ()
run1 = do
  mainWatcher@(INotify _ _ _ _ eventsThread) <- initINotify
  void $ addWatch mainWatcher [MoveIn, Create, DeleteSelf] "." (void . async . action "THREAD")
  withAsync (actionInternals "MAIN") wait
  wait eventsThread
  killINotify mainWatcher

run2 :: IO ()
run2 = do
  mainWatcher@(INotify _ _ _ _ eventsThread) <- initINotify
  void $ addWatch mainWatcher [MoveIn, Create, DeleteSelf] "." (void . async . action "THREAD")
  wait eventsThread
  killINotify mainWatcher

run3 :: IO ()
run3 = do
  mainWatcher <- initINotify
  void $ addWatch mainWatcher [MoveIn, Create, DeleteSelf] "." (void . async . action "THREAD")
  killINotify mainWatcher

run4 :: IO ()
run4 = withINotify $ \inot -> do
  void $ addWatch inot [MoveIn, Create, DeleteSelf] "." (void . async . action "THREAD")


run5 :: IO ()
run5 = do
  mainWatcher <- initINotify
  void $ addWatch mainWatcher [MoveIn, Create, DeleteSelf] "." (void . async . action "THREAD")

async version -- 2.2.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants