`retry` family of functions in Control.Exception
There is a strange behavior on Windows where deleting the parent directory of a recently-removed child directory fails. This happens because a file/directory may still be used by a program (e.g. antivirus) for a very short amount of time (<100us).
This problem arose while working on the
hakyll package, where on Windows only, some tests would fail because directories were not completely removed. The solution, proposed here, was to retry to remove directories, with a small delay between tries.
Related problems have been discussed on the issue tracker for the
win32 library and on the issue tracker for the
directory library. The consensus seems to be that retrying is general enough to warrant implementing this in
base, rather than
I am proposing to add a family of
retry functions to the
Control.Exception module which might look like this:
import Control.Exception.Base (Exception) -- Retry computation at most \n\ times for selected exceptions. retry :: Exception e => (e -> Bool) -- ^ Exception predicate -> Int -- ^ Maximum number of retries -> IO a -> IO a -- Retry computation at most \n\ times for selected exceptions. -- An action (such as a cleanup or delay) will be performed before every retry. retryWith :: Exception e => (e -> Bool) -- ^ Exception predicate -> IO () -- ^ Cleanup action -> Int -- ^ Maximum number of retries -> IO a -> IO a
Some implementations can be found on Hackage, e.g. in the
extra library. However, given the motivation for retrying to delete directories on Windows, I believe that the community should coalesce on a "central" retrying mechanism.
Given interest for this feature, I volunteer to put together a pull request.