{"action":"created","issue":{"url":"https://api.github.com/repos/ndmitchell/ghcid/issues/51","repository_url":"https://api.github.com/repos/ndmitchell/ghcid","labels_url":"https://api.github.com/repos/ndmitchell/ghcid/issues/51/labels{/name}","comments_url":"https://api.github.com/repos/ndmitchell/ghcid/issues/51/comments","events_url":"https://api.github.com/repos/ndmitchell/ghcid/issues/51/events","html_url":"https://github.com/ndmitchell/ghcid/pull/51","id":137996418,"number":51,"title":"Interruptible test command","user":{"login":"luigy","id":817138,"avatar_url":"https://avatars.githubusercontent.com/u/817138?v=3","gravatar_id":"","url":"https://api.github.com/users/luigy","html_url":"https://github.com/luigy","followers_url":"https://api.github.com/users/luigy/followers","following_url":"https://api.github.com/users/luigy/following{/other_user}","gists_url":"https://api.github.com/users/luigy/gists{/gist_id}","starred_url":"https://api.github.com/users/luigy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/luigy/subscriptions","organizations_url":"https://api.github.com/users/luigy/orgs","repos_url":"https://api.github.com/users/luigy/repos","events_url":"https://api.github.com/users/luigy/events{/privacy}","received_events_url":"https://api.github.com/users/luigy/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":20,"created_at":"2016-03-02T21:21:16Z","updated_at":"2016-03-11T22:26:58Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/ndmitchell/ghcid/pulls/51","html_url":"https://github.com/ndmitchell/ghcid/pull/51","diff_url":"https://github.com/ndmitchell/ghcid/pull/51.diff","patch_url":"https://github.com/ndmitchell/ghcid/pull/51.patch"},"body":"First pass at stealing ordeal's approach\r\nWanted to get this rolling so hopefully someone picks it up :)\r\n here is a 30 second [clip](https://cldup.com/tu8euZobN1.mp4) of the new behavior\r\n\r\n* added a `--spawn` flag that would background the test command and restart it on file change.\r\n\r\nTODO:\r\n\r\n- [x] control-c should kill the --test command before exiting. Currently the spawned process is left running.\r\n- ~~[ ] stream tests ?~~\r\n- [ ] Interpret exit code perhaps? Fold a successful test run back into \"All good\"\r\n- ~~[ ] Render test output nice~~"},"comment":{"url":"https://api.github.com/repos/ndmitchell/ghcid/issues/comments/195580000","html_url":"https://github.com/ndmitchell/ghcid/pull/51#issuecomment-195580000","issue_url":"https://api.github.com/repos/ndmitchell/ghcid/issues/51","id":195580000,"user":{"login":"luigy","id":817138,"avatar_url":"https://avatars.githubusercontent.com/u/817138?v=3","gravatar_id":"","url":"https://api.github.com/users/luigy","html_url":"https://github.com/luigy","followers_url":"https://api.github.com/users/luigy/followers","following_url":"https://api.github.com/users/luigy/following{/other_user}","gists_url":"https://api.github.com/users/luigy/gists{/gist_id}","starred_url":"https://api.github.com/users/luigy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/luigy/subscriptions","organizations_url":"https://api.github.com/users/luigy/orgs","repos_url":"https://api.github.com/users/luigy/repos","events_url":"https://api.github.com/users/luigy/events{/privacy}","received_events_url":"https://api.github.com/users/luigy/received_events","type":"User","site_admin":false},"created_at":"2016-03-11T22:26:58Z","updated_at":"2016-03-11T22:26:58Z","body":">For the interrupt thing, I still don't fully understand. Are you saying your GHCi test command spawns a p rocess itself? \r\n\r\n> Before figuring out how to send interrupts and deal with signals I'd like to be convinced that we need to go anywhere near this area at all - as far as I can tell sending Ctrl-C kills ghcid which should end up with ghci dying which should end up with spawned tasks dying. \r\n\r\nI meant that after Control-C `ghciddd` process died, but  the spawned \"ghci\"(and it's child processes)  from `createProcess` did not.\r\n\r\nHere are some images of the behavior I'm seeing without handling Control-C...\r\n\r\n## create_group=False\r\n### Running\r\n![running](https://cldup.com/ABeQUdQxEa.jpg)\r\n### Control-C on ghciddd\r\n![Control-C](https://cldup.com/cbUNnV7I-I.jpg)\r\n\r\n## create_group=True\r\n### Running\r\n![running](https://cldup.com/rF0ch_xGnY.jpg)\r\n### Control-C on ghciddd\r\n![Control-C](https://cldup.com/gIPVi3laeS.jpg)\r\n\r\n\r\n\r\n> This is helpful in circumstances where terminating the main thread does not cause a full termination of the application.\r\n\r\n:hand: Wait a second! are you saying that ghciddd's child processes like `ghci`, `cabal ghci`, etc(created by `createProcess`) might not always receive a signal on `Control-C`?\r\nif so, this explains why my spawned process(from createProcess) was left alive when hitting Control-C on ghciddd\r\n\r\n>On unix systems, I recommend using pid <- forkProcess myMain, and later doing signalProcess sigKILL pid. See my comment here.\r\n\r\nwhat do we mean by later doing? catching UserInterrupt?\r\n...\r\n> . This works extremely well in practice, I have written a ghci driver that uses this approach. ide-backend also used this approach.\r\n\r\n...wait, what!!!  so you mean it as an alternative to sending sigINT for _reloading_ (:reload) + _rerunning_ (:test_cmd) the \"test\" command passed to ghciddd? :open_mouth:\r\n\r\n>forkProcess creates a new process separate from your Ghci process, which efficiently uses a copy-on-write scheme in memory. So, you get an entirely new process which can be killed without terminating your ghci session.\r\n\r\n!!!!! I have to go see some code + test it + inspect it with htop to let this sink in :)\r\n\r\nI guess this could be an alternative to the current approach, but what about the Control-C issue?\r\n\r\nWhat an odd behavior on Control-C with create_group=False :confused: \r\n@ndmitchell I think that at least in `unix` it is probably more reliable to use a combination of `createProcess` with `create_group=True` and `installHandler`(which uses sigaction under the hood) to get more guaranteed control what actually happens on Control-C.  \r\nFrom what I understand the create_group gives us a fresh group process id that we can send signals with more confidence.\r\nI'm sure y'all been probably doing this a bit longer than me and I want to learn, so let's discuss :)\r\n\r\n-- \r\n\r\n@ndmitchell also apart from the Control-C issue does the reloading of test command work of windows?\r\nI was hoping maybe 2c966aa was enough :cold_sweat: \r\n"}}