[Haskell-cafe] File locking wishlist

Joachim Breitner mail at joachim-breitner.de
Thu Jun 5 11:22:44 EDT 2008


Hi,

for a program of mine (darcswatch[1]), a rather long running process is
run at certain events (by cron, and by new emails). I want to achieve
that:
 * Only one instance of the program runs at a time.
 * If new events come in while the program runs, it should re-run itself
 * There is information attached to the events (only one Bool ATM)

So I’d like to implement something with this, or a similar, interface:

=======================================================================
module MyLocking where

-- | tries to get the lock. If it fails, notifies the running process
--   to re-start itself afterwards, with the given information
--   returns True if the lock was aquired
lockOrMark :: Show a => FilePath -> a -> IO Bool

-- | release the lock. If new events have come in, they are returned
--   in the list, and the lock is still kept. If the list is empty,
--   the lock was successfully released.
releaseLock :: Read a => FilePath -> IO [a]
=======================================================================

I would use this module in this way:

realWork args = do
  someStuff args
  newArgs <- releaseLock "someDir/"
  unless (null newArgs) $ do
    -- we missed some events, so re-run and then try again.
    let newArg = combineInSomeWay newArgs
    realWork newArg 

main = do
  args <- getArgs
  l <- lockOrMark "someDir/" args
  when l $ do
    -- we got the lock, so lets work
    realWork args
    
I hope this makes the idea clear.


How could a possible implementation look like, when all operations
should be atomic? I was considering this, would it work fine?

lockOrMark would try to create a directory in the path. Whoever creates
the directory has the lock. If it works, create. If it fails, because
the directory already exists, then write the given args to a temporary
file with a unique name, and move it into that directory. If that fails
(because the directory has disappeared, i.e. the lock released), start
over with trying to create the directory. If it works, then you are
done.

releaseLock would try to rmdir the directory. If that succeeds, no files
have been in there, so no events were missed. If it does not succeed,
then there were files. Read and delete them and return the list of
arguments contained in them.


Greetings,
Joachim


[1] http://darcswatch.nomeata.de/

-- 
Joachim Breitner
  e-Mail: mail at joachim-breitner.de
  Homepage: http://www.joachim-breitner.de
  ICQ#: 74513189
  Jabber-ID: nomeata at joachim-breitner.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Dies ist ein digital signierter Nachrichtenteil
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20080605/ace60177/attachment.bin


More information about the Haskell-Cafe mailing list