ghcid icon indicating copy to clipboard operation
ghcid copied to clipboard

Q: Under what circumstances does GHCid do a full restart of the underlying GHCi instead of a soft `:reload`?

Open Wizek opened this issue 7 years ago • 4 comments

I have a larger project on which this is getting noticeable and annoying, and I am not quite sure why it happens. Is it perhaps that GHCid is trying to send Ctrl+C, and listens with a timeout whether that was successful? I might want to look into some verbose output. And at the same time, it might make sense for GHCid to be a bit more forthright about what it does and why, e.g.: "Interrupting didn't succeed for 2 seconds, killing GHCi and relaunching.".

What do you think?

Edit: I know about this being a feature for modifying the .cabal file and that's all nice and useful. However these full restarts happen even when I am only editing .hs files as well.

Wizek avatar Aug 17 '18 10:08 Wizek

Here is the verbose output:

%STDOUT: 

%STDOUT: Finished in 20.1611 seconds
Finished in 20.1611 seconds
%STDOUT: 3 examples, 0 failures
3 examples, 0 failures
%NOTIFY: Modified "/home/wizek/sandbox/proj-2/src/Module.hs" 2018-08-20 14:55:14.011607004 UTC
%WAITING: Notify signaled

Reloading...
  /home/wizek/sandbox/proj-2/src/Module.hs


... (lots of empty lines omitted)


%INTERRUPT
%STDIN: INTERNAL_GHCID.putStrLn "#~GHCID-FINISH-19~#"
INTERNAL_GHCID.hPutStrLn INTERNAL_GHCID.stderr "#~GHCID-FINISH-19~#"
Loading stack ghci --flag proj:-BundleFoo proj:exe:proj-dev ...
%INTERRUPT
%STDIN: INTERNAL_GHCID.putStrLn "#~GHCID-FINISH-19~#"
INTERNAL_GHCID.hPutStrLn INTERNAL_GHCID.stderr "#~GHCID-FINISH-19~#"
%STDERR: WARNING: Ignoring out of range dependency (allow-newer enabled): directory-1.3.0.0. shelly requires: >=1.1.0.0 && <1.3.0.0
%STDOUT2: WARNING: Ignoring out of range dependency (allow-newer enabled): directory-1.3.0.0. shelly requires: >=1.1.0.0 && <1.3.0.0
WARNING: Ignoring out of range dependency (allow-newer enabled): directory-1.3.0.0. shelly requires: >=1.1.0.0 && <1.3.0.0
%STDERR: proj-0.23.10: initial-build-steps (exe)
%STDOUT2: proj-0.23.10: initial-build-steps (exe)
proj-0.23.10: initial-build-steps (exe)

Does this give you any ideas what might be going wrong, @ndmitchell?

Wizek avatar Aug 20 '18 15:08 Wizek

No, and I don't think I say when I've given up on a timeout. I think the code that is hitting you is probably at: https://github.com/ndmitchell/ghcid/blob/master/src/Session.hs#L132-L139. I'd welcome a patch adding more logging around there.

It seems to sent the interrupt that you must be running code with --test? And that on interupt that code doesn't terminate in 5s? To reproduce, use ghci, then run your test, then hit Ctrl-C. If your test doesn't react to Ctrl-C within 5s then ghcid will have to restart everything.

ndmitchell avatar Aug 20 '18 21:08 ndmitchell

Indeed, something seems to be catching and discarding UserInterrupts in my app. How unfortunate. And thank you for validating my suspicion on how GHCid works in this case. Are you open for me sending in a PR with some more logging? e.g. saying "Interrupt wasn't handled for 5 seconds, fully restarting GHCi.".

Somewhat off topic from this ticket: since your name and blog post comes up quite a bit when I search around for 'Haskell Control+C handling', might you have an idea how I could find out where the discarding happens? E.g. I was thinking I could try to somehow wrap installHandler and catch with some extra logic that would enable me to Debug.Trace the relevant line number if any of them try to silently discard UserInterrupts. Maybe if I edit base this is possible?... Any other ideas?

Wizek avatar Aug 21 '18 04:08 Wizek

@Wizek yep, very open to such a message. Either logging via --verbose or in this case I think normal stdout is valid.

http://neilmitchell.blogspot.com/2015/05/handling-control-c-in-haskell.html is everything I know. My suggestion for the cheaters is just to do the trick as per "How to robustly deal with UserInterrupt?". If you want to try harder then write onException everywhere and print statements in the handler. Where the prints stop happening is where the exception gets swallowed. Depending on the audience of the program, the cheating method is quite legitimate.

ndmitchell avatar Aug 21 '18 09:08 ndmitchell