Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hint-0.8.0] removeDirectory: unsatisfied constraints (Directory not empty) #78

Closed
limick opened this issue Nov 6, 2018 · 14 comments
Closed

Comments

@limick
Copy link

limick commented Nov 6, 2018

I have a web application using the Snap web framework which (when compiled in development mode) uses a library called snap-loader-dynamic which in turn uses hint.
After starting the app and making a request, the console shows:

no port specified, defaulting to port 8000
Listening on http://0.0.0.0:8000
myapp-run: /tmp/hint-50920120ee965b0f: removeDirectory: unsatisfied constraints (Directory not empty)

The request handler does not return anything, it just gets killed after a timeout.
The temporary directory indeed contains a file: M512069275886764874574.txt. (File extension changed from .dump-hi to .txt due to GitHub restrictions.)

Relevant versions

  • stackage LTS-12.15
  • GHC-8.4.4
  • hint 0.8.0
  • snap 1.1.1.0
  • snap-core 1.0.3.2
  • snap-loader-dynamic 1.0.0.0
  • cabal-install version 2.2.0.0
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.1 LTS
Release:	18.04
Codename:	bionic
@limick
Copy link
Author

limick commented Nov 6, 2018

I've created a repository that reproduces the bug reliably on my machine.
Note that the bug also appears when using hint-0.9.0.

@nwg
Copy link

nwg commented Dec 25, 2018

@limick did you ever make any progress on this? I noticed that with a standard "cabal new-install", the problem does not surface. The presence of the .dump-hi file appears related to the use of stackage. According to https://stackoverflow.com/questions/46397802/how-to-prevent-stack-from-creating-dump-hi-files , the dump-hi files are related to stack and template haskell. Not sure how to proceed at this point.

@limick
Copy link
Author

limick commented Dec 26, 2018

@nwg I did not make any progress yet, I went back to using stackage LTS-11.22, which uses hint-0.7.0. Thanks for your hint about using cabal new-install. I tried it on the reproduction repository linked to above and indeed the problem did not appear. I'm not familiar enough with cabal to figure out why there is a difference between stack build and cabal new-build. It could be that cabal uses hint-0.7.0.
In any case, my guess is that the problem arises in hint-0.8.0 because of the changes to temporary files for phantom modules, mentioned in the changelog. I tried to look at the relevant diffs but I didn't see anything obvious.
Edit: My reading of the SO question you link to is not necessarily that the .dump-hi files are related to stack, but simply that (at least with stack) there is no way to prevent them from being generated.

@nwg
Copy link

nwg commented Dec 26, 2018

One fix is to use a custom hint with removeDirectoryRecursive in place of removeDirectory. I tried that and it seems to work fine. Another fix would be to derive the .dump-hi filename and delete that if it exists, too. I don't know what the best change to send upstream is yet, though.

@gelisam gelisam closed this as completed Dec 26, 2018
@gelisam gelisam reopened this Dec 26, 2018
@gelisam
Copy link
Contributor

gelisam commented Dec 26, 2018

I have a web application using the Snap web framework which (when compiled in development mode) uses a library called snap-loader-dynamic which in turn uses hint.
[...]
I've created a repository that reproduces the bug reliably on my machine.

While it's good to have a reliable repro case, I would prefer to have a minimal repro case which only uses hint, not snap. Presumably, snap does something special which causes this .dump-hi file to appear? It is clear that the fix is to delete the file, but it is not clear whether it should it be snap's responsibility to delete that file, or hint's.

@gelisam
Copy link
Contributor

gelisam commented Dec 27, 2018

the dump-hi files are related to stack and template haskell

Turns out the temporary file doesn't contain much:

module M001( 
    String_M001,
    show_M001)
where

import qualified Prelude as Prelude_M001 (String, Show(show))

type String_M001 = Prelude_M001.String

show_M001 :: Prelude_M001.Show a => a -> Prelude_M001.String
show_M001 = Prelude_M001.show

In particular, it does not contain any template-haskell code. So what is snap doing which is causing those .dump-hi files to appear? I don't get them when I use stack to build and run a simple program such as the following.

import Language.Haskell.Interpreter

main :: IO ()
main = do
  r <- runInterpreter $ do
    setImports ["Prelude"]
    interpret "42" (as :: Int)
  print r

@nwg
Copy link

nwg commented Dec 27, 2018

I think the simple program itself has to use template haskell, and the dump-hi files are there to help with recompilation of modules that use TH. In snap's case, it is running the interpreter inside quotes inside a TH function. I'm not totally sure how the dump-hi system works, though, and this is just based off some simple google searching.

More info on exactly what snap itself is doing: it's using a splice to generate a call to a function (in bracket quotes) that calls unsafeRunInterpreterWithArgs at runtime.

I am also trying to reproduce this in a simple project.

@nwg
Copy link

nwg commented Dec 27, 2018

Also, if you are curious the relevant snap code is in snap-loader-dynamic in the file src/Snap/Loader/Dynamic.hs

@gelisam
Copy link
Contributor

gelisam commented Dec 27, 2018

Thanks. I've managed to track it down to:

This call to unsafeRunInterpreterWithArgs passes many extra arguments to the underlying ghci context, including -ddump-hi, which is what causes the file to be created. So I'd say that it is clearly snap-loader-dynamic which is causing the .dump-hi files to be created, not hint :)

Still, since the file is created in a temporary folder which is created by hint, not by snap-loader-dynamic, it's not clear how snap-loader-dynamic could remove the file even if we decided that it was snap-loader-dynamic's responsibility to do so. Could you explain why snap-loader-dynamic needs to pass this parameter to hint?

@nwg
Copy link

nwg commented Dec 27, 2018

I can't explain why it's needed because i don't know enough about how it works.I might be able to get some help on IRC.

@gelisam
Copy link
Contributor

gelisam commented Dec 27, 2018

In particular, I notice that snap-loader-dynamic already strips away some options from wherever it's getting its list from, such as -threaded and -static. Maybe it should strip -ddump-hi as well?

@nwg
Copy link

nwg commented Dec 28, 2018

I am not yet totally sure, but i think removing -ddump-hi will do the trick and be proper here. I've tested that it works and i think the interpreted environment will work better without it.

@gelisam
Copy link
Contributor

gelisam commented Dec 28, 2018

Great! Closing then.

@gelisam gelisam closed this as completed Dec 28, 2018
@limick
Copy link
Author

limick commented Dec 28, 2018

Many thanks to both of you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants