how to implement daemon start and stop directives?

Hi! Could somebody please share some experience on how to implement daemon start and stop directives. In theory I need something like this: 1. "my_daemon start" - starts my app with an infinite loop of serving inside. 2. "my_daemon stop" - puts in some TVar a value signalizing, that stop is given - infinite loop brakes. 3. ...it on Linux platform. Thanks in advance! -- View this message in context: http://www.nabble.com/how-to-implement-daemon-start-and-stop-directives--tp2... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

On Wed, Jan 21, 2009 at 11:36 PM, Belka
Hi!
Could somebody please share some experience on how to implement daemon start and stop directives. In theory I need something like this: 1. "my_daemon start" - starts my app with an infinite loop of serving inside. 2. "my_daemon stop" - puts in some TVar a value signalizing, that stop is given - infinite loop brakes.
You can abstract this pattern: -- runs its argument in an infinite loop, and returns an action that stops the loop daemon :: IO () -> IO (IO ()) daemon action = do stopvar <- atomically $ newTVar False let run = do stop <- atomically $ readTVar stopvar if stop then return () else (action >> run) forkIO run return (atomically $ writeTVar stopvar True) TVars are overkill here, actually, an IORef would be just fine, I think. Luke

You can abstract this pattern:
-- runs its argument in an infinite loop, and returns an action that stops the loop daemon :: IO () -> IO (IO ()) daemon action = do stopvar <- atomically $ newTVar False let run = do stop <- atomically $ readTVar stopvar if stop then return () else (action >> run) forkIO run return (atomically $ writeTVar stopvar True)
TVars are overkill here, actually, an IORef would be just fine, I think.
Luke
Thanks, Luke! Why do you write "return (atomically $ writeTVar stopvar True)" in the end? Actually, I'm more interested in technical details how to communicate from shell with background process - how to send commands to it. Currently looking into POSIX libraries hope to find answers there... Also, maybe a FIFO-pipe-file would solve my problem. Imagine writing a command in it, while one of daemon's thread is locked-while-awaits for anything to come out from the other side of the pipe... Belka -- View this message in context: http://www.nabble.com/how-to-implement-daemon-start-and-stop-directives--tp2... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Although I am not Luke, I will answer :)
The code creates a TVar 'stopvar', whose truth means to the 'run' loop
that it's time to return ().
So, if we're going to return an action that stops the loop, we're
going to return an action that sets stopvar to True.
That's precisely what return (atomically $ writeTVar stopvar True)
does. In case you're wondering about the atomically, it's because
writeTVar .... has type STM () and whereas we need to 'return' an IO
(). For precisely the same reason is atomically present in the run
loop, since the loop is also in the IO monad.
2009/1/22 Belka
You can abstract this pattern:
-- runs its argument in an infinite loop, and returns an action that stops the loop daemon :: IO () -> IO (IO ()) daemon action = do stopvar <- atomically $ newTVar False let run = do stop <- atomically $ readTVar stopvar if stop then return () else (action >> run) forkIO run return (atomically $ writeTVar stopvar True)
TVars are overkill here, actually, an IORef would be just fine, I think.
Luke
Thanks, Luke!
Why do you write "return (atomically $ writeTVar stopvar True)" in the end?
Actually, I'm more interested in technical details how to communicate from shell with background process - how to send commands to it. Currently looking into POSIX libraries hope to find answers there... Also, maybe a FIFO-pipe-file would solve my problem. Imagine writing a command in it, while one of daemon's thread is locked-while-awaits for anything to come out from the other side of the pipe...
Belka -- View this message in context: http://www.nabble.com/how-to-implement-daemon-start-and-stop-directives--tp2... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Евгений Кирпичев Разработчик Яндекс.Маркета

On Thu, Jan 22, 2009 at 8:11 AM, Belka
You can abstract this pattern:
-- runs its argument in an infinite loop, and returns an action that stops the loop daemon :: IO () -> IO (IO ()) daemon action = do stopvar <- atomically $ newTVar False let run = do stop <- atomically $ readTVar stopvar if stop then return () else (action >> run) forkIO run return (atomically $ writeTVar stopvar True)
TVars are overkill here, actually, an IORef would be just fine, I think.
Luke
Thanks, Luke!
Why do you write "return (atomically $ writeTVar stopvar True)" in the end?
Actually, I'm more interested in technical details how to communicate from shell with background process - how to send commands to it. Currently looking into POSIX libraries hope to find answers there... Also, maybe a FIFO-pipe-file would solve my problem. Imagine writing a command in it, while one of daemon's thread is locked-while-awaits for anything to come out from the other side of the pipe...
I think you should follow Unix "standards" in this case. So depending on what you kind of communication you are looking for you have different options (this is based on my understanding of the Unix way): * Signals - for simple control, such as getting the daemon to stop, reread its configuration, or restart * Pipe/Socket - for more complex control such as job control /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe

On 2009 Jan 22, at 3:11, Belka wrote:
Actually, I'm more interested in technical details how to communicate from shell with background process - how to send commands to it. Currently looking into POSIX libraries hope to find answers there... Also, maybe a FIFO-pipe-file would solve my problem. Imagine writing a command in it, while one of daemon's thread is locked-while-awaits for anything to come out from the other side of the pipe...
You can try it; make sure to open the FIFO for read+write to avoid deadlocks, and I think there are some weird behaviors caused by the GHC runtime's non-blocking IO. It will be a lot easier to use a socket (AF_INET or AF_UNIX depending on whether you want to support remote access or not). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

Luke Palmer
TVars are overkill here, actually, an IORef would be just fine, I think.
Using IORefs is generally a sign of bad style. But MVars would perfectly suffice here. They would be essentially the same, but without 'atomically'. Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

On Thu, Jan 22, 2009 at 5:48 AM, Ertugrul Soeylemez
Luke Palmer
wrote: TVars are overkill here, actually, an IORef would be just fine, I think.
Using IORefs is generally a sign of bad style.
I totally disagree. The disadvantage of IORefs is that they do not work together very nicely. If you have more than one, it is very hard (impossible) to keep multithreaded invariants between them. But in this case, the IORef is completely encapsulated: it does not leave the scope in which it was created. You will never have to use it with any other IORef, because nobody else even knows it exists. The pattern is self-contained and threadsafe with just an IORef. A program that needs only IORefs and is threadsafe is *good* style to me, because it means all the state is well-encapsulated (if it escaped, it would fail to be threadsafe). Luke
But MVars would perfectly suffice here. They would be essentially the same, but without 'atomically'.

Luke Palmer
On Thu, Jan 22, 2009 at 5:48 AM, Ertugrul Soeylemez
wrote: Luke Palmer
wrote: TVars are overkill here, actually, an IORef would be just fine, I think.
Using IORefs is generally a sign of bad style.
I totally disagree.
The disadvantage of IORefs is that they do not work together very nicely. If you have more than one, it is very hard (impossible) to keep multithreaded invariants between them.
But in this case, the IORef is completely encapsulated: it does not leave the scope in which it was created. You will never have to use it with any other IORef, because nobody else even knows it exists. The pattern is self-contained and threadsafe with just an IORef.
A program that needs only IORefs and is threadsafe is *good* style to me, because it means all the state is well-encapsulated (if it escaped, it would fail to be threadsafe).
That's not my point. The use of IORefs indicates an imperative programming style. Sometimes this is inevitable, but I've never seen a case, where IORefs couldn't be replaced by a more elegant State/StateT-based solution. And if you need to do multi-threading, Chans, MVars and semaphores are better anyway. There is no reason to prefer an IORef over an MVar to signal something to another thread. By the way, IORefs are by themselves not thread-safe. You need to use a special function, when using it in a multi-threaded manner. Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

On Thu, Jan 22, 2009 at 9:04 AM, Ertugrul Soeylemez
A program that needs only IORefs and is threadsafe is *good* style to me, because it means all the state is well-encapsulated (if it escaped, it would fail to be threadsafe).
That's not my point. The use of IORefs indicates an imperative programming style.
Um, we were talking about IORefs vs. MVars or TVars. I thought we were already firmly in the imperative world. Nobody on this list will argue against a pure solution always being preferable.
Sometimes this is inevitable, but I've never seen a case, where IORefs couldn't be replaced by a more elegant State/StateT-based solution. And if you need to do multi-threading, Chans, MVars and semaphores are better anyway.
Please define "better". For the function in question, what advantages do they give us? Just to be clear, I wouldn't dare argue that IORefs can do everything MVars and TVars can do. I'm just perplexed why you say MVars and TVars are better, when an IORef does the trick just fine for our function. There is no reason to
prefer an IORef over an MVar to signal something to another thread.
Well, I usually don't go here, but benchmarks show that IORefs are the fastest of any of the mutable variable primitives, by at least a factor of 2. I wish I remembered where I saw that.
By the way, IORefs are by themselves not thread-safe. You need to use a special function, when using it in a multi-threaded manner.
You mean atomicModifyIORef? IORefs *are* thread-safe by themselves: you will not make your program segfault by using them in a multithreaded program. So it all comes down to invariants. IORefs have no synchronization concepts, so code like: x <- readIORef ref writeIORef ref (x+1) Is not threadsafe by most standards. That doesn't mean IORefs themselves are not threadsafe, just that you have to be careful how you use them. And I will reiterate: *in this case* the use of IORef is fully encapsulated in this function and *is threadsafe!* Which is the basis of my argument: in imperative code, when you can limit the scope of an IORef to a small abstraction that is threadsafe, there is no advantage of TVars or MVars over them. I don't think they deserve "bad style" sledgehammer. (An instance of "use the right tool for the job") daemon :: IO () -> IO (IO ()) daemon action = do stopvar <- newIORef False let run = do stop <- readIORef stopvar if stop then return () else (action >> run) forkIO run return (writeIORef stopvar True) Luke

Luke Palmer
On Thu, Jan 22, 2009 at 9:04 AM, Ertugrul Soeylemez
wrote: Sometimes this is inevitable, but I've never seen a case, where IORefs couldn't be replaced by a more elegant State/StateT-based solution. And if you need to do multi-threading, Chans, MVars and semaphores are better anyway.
Please define "better". For the function in question, what advantages do they give us?
It gives you thread-safety for free, which IORefs don't give you. It's the same purpose, the same amount of code, but threadsafe by concept. Of course, for simple variables, IORefs will likely be thread-safe as well, but there is no guarantee here. With MVars you have that guarantee.
Just to be clear, I wouldn't dare argue that IORefs can do everything MVars and TVars can do. I'm just perplexed why you say MVars and TVars are better, when an IORef does the trick just fine for our function.
What I'm saying is: Even if IORefs suffice, why would you want to use them, if MVar does the job as well and likely better?
There is no reason to prefer an IORef over an MVar to signal something to another thread.
Well, I usually don't go here, but benchmarks show that IORefs are the fastest of any of the mutable variable primitives, by at least a factor of 2. I wish I remembered where I saw that.
Yes, that's a good point, but I think, you can safely disregard that for signalling a thread to quit.
By the way, IORefs are by themselves not thread-safe. You need to use a special function, when using it in a multi-threaded manner.
You mean atomicModifyIORef?
Yes.
IORefs *are* thread-safe by themselves: you will not make your program segfault by using them in a multithreaded program. So it all comes down to invariants. IORefs have no synchronization concepts, so code like:
x <- readIORef ref writeIORef ref (x+1)
Is not threadsafe by most standards. That doesn't mean IORefs themselves are not threadsafe, just that you have to be careful how you use them.
That's exactly my point. In the above case they do just the same, but need more care.
And I will reiterate: *in this case* the use of IORef is fully encapsulated in this function and *is threadsafe!* Which is the basis of my argument: in imperative code, when you can limit the scope of an IORef to a small abstraction that is threadsafe, there is no advantage of TVars or MVars over them. I don't think they deserve "bad style" sledgehammer. (An instance of "use the right tool for the job")
daemon :: IO () -> IO (IO ()) daemon action = do stopvar <- newIORef False let run = do stop <- readIORef stopvar if stop then return () else (action >> run) forkIO run return (writeIORef stopvar True)
In this case, it's simply a coincidence that it's safe. It's because you're using an IORef Bool, and because writes to a Bool variable are atomic on virtually all platforms. An Integer may already fail to be thread-safe. You need more care and the payoff is zero. If you still insist on using IORefs, at least use the atomic function above, but that destroys the little performance benefit of using IORefs, unless GHC does some intelligent optimization here, which I doubt. Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

2009/1/23 Ertugrul Soeylemez
Luke Palmer
wrote: On Thu, Jan 22, 2009 at 9:04 AM, Ertugrul Soeylemez
wrote: Sometimes this is inevitable, but I've never seen a case, where IORefs couldn't be replaced by a more elegant State/StateT-based solution. And if you need to do multi-threading, Chans, MVars and semaphores are better anyway.
Please define "better". For the function in question, what advantages do they give us?
It gives you thread-safety for free, which IORefs don't give you. It's the same purpose, the same amount of code, but threadsafe by concept. Of course, for simple variables, IORefs will likely be thread-safe as well, but there is no guarantee here. With MVars you have that guarantee.
Just to be clear, I wouldn't dare argue that IORefs can do everything MVars and TVars can do. I'm just perplexed why you say MVars and TVars are better, when an IORef does the trick just fine for our function.
What I'm saying is: Even if IORefs suffice, why would you want to use them, if MVar does the job as well and likely better?
There is no reason to prefer an IORef over an MVar to signal something to another thread.
Well, I usually don't go here, but benchmarks show that IORefs are the fastest of any of the mutable variable primitives, by at least a factor of 2. I wish I remembered where I saw that.
Yes, that's a good point, but I think, you can safely disregard that for signalling a thread to quit.
By the way, IORefs are by themselves not thread-safe. You need to use a special function, when using it in a multi-threaded manner.
You mean atomicModifyIORef?
Yes.
IORefs *are* thread-safe by themselves: you will not make your program segfault by using them in a multithreaded program. So it all comes down to invariants. IORefs have no synchronization concepts, so code like:
x <- readIORef ref writeIORef ref (x+1)
Is not threadsafe by most standards. That doesn't mean IORefs themselves are not threadsafe, just that you have to be careful how you use them.
That's exactly my point. In the above case they do just the same, but need more care.
And I will reiterate: *in this case* the use of IORef is fully encapsulated in this function and *is threadsafe!* Which is the basis of my argument: in imperative code, when you can limit the scope of an IORef to a small abstraction that is threadsafe, there is no advantage of TVars or MVars over them. I don't think they deserve "bad style" sledgehammer. (An instance of "use the right tool for the job")
daemon :: IO () -> IO (IO ()) daemon action = do stopvar <- newIORef False let run = do stop <- readIORef stopvar if stop then return () else (action >> run) forkIO run return (writeIORef stopvar True)
In this case, it's simply a coincidence that it's safe. It's because you're using an IORef Bool, and because writes to a Bool variable are atomic on virtually all platforms. An Integer may already fail to be thread-safe. You need more care and the payoff is zero. If you still insist on using IORefs, at least use the atomic function above, but that destroys the little performance benefit of using IORefs, unless GHC does some intelligent optimization here, which I doubt.
This would be the case if the IORef was unboxed, but it is boxed, so writing an IORef is actually writing a pointer to a thunk; here, Bool and Integer have no difference at all. However, I don't know whether GHC makes pointer writes atomic on all platforms (Java does, so it's at least doable).
Greets, Ertugrul.
-- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Eugene Kirpichov
daemon :: IO () -> IO (IO ()) daemon action = do stopvar <- newIORef False let run = do stop <- readIORef stopvar if stop then return () else (action >> run) forkIO run return (writeIORef stopvar True)
In this case, it's simply a coincidence that it's safe. It's because you're using an IORef Bool, and because writes to a Bool variable are atomic on virtually all platforms. An Integer may already fail to be thread-safe. You need more care and the payoff is zero. If you still insist on using IORefs, at least use the atomic function above, but that destroys the little performance benefit of using IORefs, unless GHC does some intelligent optimization here, which I doubt.
This would be the case if the IORef was unboxed, but it is boxed, so writing an IORef is actually writing a pointer to a thunk; here, Bool and Integer have no difference at all. However, I don't know whether GHC makes pointer writes atomic on all platforms (Java does, so it's at least doable).
It will likely work, but the compiler is not required to make pointer writes atomic, and it would be an enormous performance hit. The pointer write is more likely atomic by platform, not by the code, but even there I would be very careful, because it may be not the case for SMP systems. And you know what happens, when a pointer race condition occurs. The selection between MVar and IORef is essentially a "security or performance" question. Especially for daemons I would rather choose security. MVar gives you that security with _the same amount of code_. And to prove that IORefs do lead to a pointer race condition and hence are insecure, try the following code: main :: IO () main = do ref <- newIORef False forkIO $ forever $ modifyIORef ref not forever $ readIORef ref >>= print It crashes for me. I'm using GHC 6.10.1 on an Athlon 64 X2 (32 bits system). The error message reads: test: internal error: schedule: invalid what_next field (GHC version 6.10.1 for i386_unknown_linux) Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

Ertugrul Soeylemez wrote:
And to prove that IORefs do lead to a pointer race condition and hence are insecure, try the following code:
main :: IO () main = do ref <- newIORef False forkIO $ forever $ modifyIORef ref not forever $ readIORef ref >>= print
It crashes for me. I'm using GHC 6.10.1 on an Athlon 64 X2 (32 bits system). The error message reads:
test: internal error: schedule: invalid what_next field (GHC version 6.10.1 for i386_unknown_linux) Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
Interesting. Looks like a bug in the single-threaded runtime to me: I can reproduce this crash only when compiling without the `-threaded' flag.

On 2009 Jan 22, at 1:36, Belka wrote:
Could somebody please share some experience on how to implement daemon start and stop directives. In theory I need something like this: 1. "my_daemon start" - starts my app with an infinite loop of serving inside. 2. "my_daemon stop" - puts in some TVar a value signalizing, that stop is given - infinite loop brakes. 3. ...it on Linux platform.
Thanks in advance!
If you want a normal daemon, you want to look at System.Posix.Process to create a proper daemon (forkProcess, createSession; don't forget to close stdOutput (and, errr, Haskell library types: stdin and stderr are where? not System.Posix.IO with stdOutput) and reopen them on / dev/null, at least if they're ttys as determined by System.Posix.Terminal.queryTerminal). You also want to write out a pidfile (/var/run/programname.pid) for use by startproc / killproc, and you want to install a handler for sigTERM (System.Posix.Signals.installHandler) which sets the exit flag (TVar, MVar, IORef, Chan, take your pick). Ideally you also catch sigHUP and reload your state. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

If you want a normal daemon, you want to look at System.Posix.Process to create a proper daemon (forkProcess, createSession; don't forget to close stdOutput (and, errr, Haskell library types: stdin and stderr are where? not System.Posix.IO with stdOutput) and reopen them on / dev/null, at least if they're ttys as determined by System.Posix.Terminal.queryTerminal). You also want to write out a pidfile (/var/run/programname.pid) for use by startproc / killproc, and you want to install a handler for sigTERM (System.Posix.Signals.installHandler) which sets the exit flag (TVar, MVar, IORef, Chan, take your pick). Ideally you also catch sigHUP and reload your state.
Thanks for the guide, Brandon !! By the way, I found a piece of code with function (daemonize :: IO () -> IO ()) (http://sneakymustard.com/2008/12/11/haskell-daemons), which is close to the subject. I guess now I'm ready to implement my own daemon! Thanks for your help, everyboby!! =) -- View this message in context: http://www.nabble.com/how-to-implement-daemon-start-and-stop-directives--tp2... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

When you succeed please write about it - I'd love to read about it!I was
interested in writing a deamon in the past but didn't have time for it and a
nice tutorial would probably help a lot.
All best
Christopher Skrzętnicki
On Sun, Jan 25, 2009 at 02:57, Belka
If you want a normal daemon, you want to look at System.Posix.Process to create a proper daemon (forkProcess, createSession; don't forget to close stdOutput (and, errr, Haskell library types: stdin and stderr are where? not System.Posix.IO with stdOutput) and reopen them on / dev/null, at least if they're ttys as determined by System.Posix.Terminal.queryTerminal). You also want to write out a pidfile (/var/run/programname.pid) for use by startproc / killproc, and you want to install a handler for sigTERM (System.Posix.Signals.installHandler) which sets the exit flag (TVar, MVar, IORef, Chan, take your pick). Ideally you also catch sigHUP and reload your state.
Thanks for the guide, Brandon !!
By the way, I found a piece of code with function (daemonize :: IO () -> IO ()) (http://sneakymustard.com/2008/12/11/haskell-daemons), which is close to the subject.
I guess now I'm ready to implement my own daemon! Thanks for your help, everyboby!! =)

On 2009 Jan 25, at 6:57, Krzysztof Skrzętnicki wrote:
When you succeed please write about it - I'd love to read about it! I was interested in writing a deamon in the past but didn't have time for it and a nice tutorial would probably help a lot.
I should mention that the easiest way to write a daemon is to use inetd/xinetd (or launchd, SMF, etc. as appropriate for OS); you then only need to deal with stdin/stdout, and you generally get tcp- wrappers for free instead of having to find/make libwrap bindings. (Also, if you write yourself a nice daemon library, someone will probably ask for it to be ported to create Windows services. Which gets a big "damfino" from me, at least.) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH
participants (8)
-
Belka
-
Brandon S. Allbery KF8NH
-
Ertugrul Soeylemez
-
Eugene Kirpichov
-
Gleb Alexeyev
-
Krzysztof Skrzętnicki
-
Luke Palmer
-
Magnus Therning