title: How can I make file I/O more transactional?
body: <p>I'm writing CGI scripts in Haskell. When the user hits &lsquo;submit&rsquo;, a Haskell program runs on the server, updating (i.e. reading in, processing, overwriting) a status file. Reading then overwriting sometimes causes issues with lazy IO, as we may be able to generate a large output prefix before we've finished reading the input. Worse, users sometimes bounce on the submit button and two instances of the process run concurrently, fighting over the same file!</p>
  
  <p>What's a good way to implement</p>
  
  <pre><code>transactionalUpdate :: FilePath -&gt; (String -&gt; String) -&gt; IO ()
  </code></pre>
  
  <p>where the function (&lsquo;update&rsquo;) computes the new file contents from the old file contents? It is not safe to presume that &lsquo;update&rsquo; is strict, but it may be presumed that it is total (robustness to partial update functions is a bonus). Transactions may be attempted concurrently, but no transaction should be able to update if the file has been written by anyone else since it was read. It's ok for a transaction to abort in case of competition for file access. We may assume a source of systemwide-unique temporary filenames.</p>
  
  <p>My current attempt writes to a temporary file, then uses a system copy command to overwrite. That seems to deal with the lazy IO problems, but it doesn't strike me as safe from races. Is there a tried and tested formula that we could just bottle?</p>