{"action":"created","issue":{"url":"https://api.github.com/repos/ndmitchell/shake/issues/611","repository_url":"https://api.github.com/repos/ndmitchell/shake","labels_url":"https://api.github.com/repos/ndmitchell/shake/issues/611/labels{/name}","comments_url":"https://api.github.com/repos/ndmitchell/shake/issues/611/comments","events_url":"https://api.github.com/repos/ndmitchell/shake/issues/611/events","html_url":"https://github.com/ndmitchell/shake/issues/611","id":356593045,"node_id":"MDU6SXNzdWUzNTY1OTMwNDU=","number":611,"title":"`actionFinally` handlers can be incorrectly run twice on ctrl-C","user":{"login":"judah","id":49143,"node_id":"MDQ6VXNlcjQ5MTQz","avatar_url":"https://avatars3.githubusercontent.com/u/49143?v=4","gravatar_id":"","url":"https://api.github.com/users/judah","html_url":"https://github.com/judah","followers_url":"https://api.github.com/users/judah/followers","following_url":"https://api.github.com/users/judah/following{/other_user}","gists_url":"https://api.github.com/users/judah/gists{/gist_id}","starred_url":"https://api.github.com/users/judah/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/judah/subscriptions","organizations_url":"https://api.github.com/users/judah/orgs","repos_url":"https://api.github.com/users/judah/repos","events_url":"https://api.github.com/users/judah/events{/privacy}","received_events_url":"https://api.github.com/users/judah/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2018-09-03T20:17:15Z","updated_at":"2018-09-03T22:04:59Z","closed_at":"2018-09-03T21:36:46Z","author_association":"NONE","body":"When you Ctrl-C a Shake program, it's possible for pending `actionFinally` commands to be run *twice* by Shake.  This appears to be a race condition in Shake's cleanup code.\r\n\r\nI discovered this in judah/pier#100.  Pier uses `actionFinally` to clean up temporary directories with  Occasionally, when you control-C `pier`, you get an error message indicating that two `removeDirectoryRecursive` calls on the same temporary directory are running simultaneously.\r\n\r\nExample code to reproduce the failure: \r\n```\r\n{-# LANGUAGE DeriveAnyClass #-}\r\n{-# LANGUAGE DeriveGeneric #-}\r\n{-# LANGUAGE TypeFamilies #-}\r\nmodule Main (main) where\r\n\r\nimport Development.Shake\r\nimport Development.Shake.Classes\r\nimport Development.Shake.Rule\r\nimport GHC.Generics\r\nimport Control.Concurrent\r\n\r\nmain :: IO ()\r\nmain = shakeArgs shakeOptions $ do\r\n    r <- addOracle $ \\(MyRule k) -> do\r\n        putNormal $ \"Running \" ++ show k\r\n        let delay = do\r\n                    putStrLn $ \"Delay cleanup \" ++ show k\r\n                    threadDelay 1000000\r\n        let finish = do\r\n                    putStrLn $ \"Finish cleanup \" ++ show k\r\n                    threadDelay 1000000\r\n        liftIO (threadDelay 3000000)\r\n            `actionFinally` delay `actionFinally` finish\r\n    action $ forP [1..4] $ \\k -> r (MyRule k) >>= putNormal . show\r\n\r\ndata MyRule = MyRule Int\r\n    deriving (Show, Typeable, Eq, Generic, Hashable, Binary, NFData)\r\ntype instance RuleResult MyRule = ()\r\n```\r\n\r\nThen, run:\r\n```\r\n$ stack --resolver=lts-12.8 exec ghc -- -threaded Reproduce.hs\r\n$ ./Reproduce -j2\r\n```\r\nAnd press ctrl-C while it's still running.\r\n\r\nThe output that I got was:\r\n```\r\nRunning 1\r\nRunning 3\r\n^CDelay cleanup 3\r\nDelay cleanup 1\r\nFinish cleanup 3\r\nFinish cleanup 1\r\nFinish cleanup 3\r\nFinish cleanup 1\r\nuser interrupt\r\n```\r\n\r\nThat the messages \"Finish cleanup 1\" and \"Finish cleanup 3\" are printed *twice*, even though the corresponding \"Running\" commands are only printed once."},"comment":{"url":"https://api.github.com/repos/ndmitchell/shake/issues/comments/418198385","html_url":"https://github.com/ndmitchell/shake/issues/611#issuecomment-418198385","issue_url":"https://api.github.com/repos/ndmitchell/shake/issues/611","id":418198385,"node_id":"MDEyOklzc3VlQ29tbWVudDQxODE5ODM4NQ==","user":{"login":"judah","id":49143,"node_id":"MDQ6VXNlcjQ5MTQz","avatar_url":"https://avatars3.githubusercontent.com/u/49143?v=4","gravatar_id":"","url":"https://api.github.com/users/judah","html_url":"https://github.com/judah","followers_url":"https://api.github.com/users/judah/followers","following_url":"https://api.github.com/users/judah/following{/other_user}","gists_url":"https://api.github.com/users/judah/gists{/gist_id}","starred_url":"https://api.github.com/users/judah/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/judah/subscriptions","organizations_url":"https://api.github.com/users/judah/orgs","repos_url":"https://api.github.com/users/judah/repos","events_url":"https://api.github.com/users/judah/events{/privacy}","received_events_url":"https://api.github.com/users/judah/received_events","type":"User","site_admin":false},"created_at":"2018-09-03T22:04:59Z","updated_at":"2018-09-03T22:04:59Z","author_association":"NONE","body":"Thank you for the quick fix!  It's not urgent; waiting a few weeks for the fix is fine."}}
{"actor":{"display_login":"judah"}}