Skip to content

Conversation

imalsogreg
Copy link
Collaborator

@imalsogreg imalsogreg commented Mar 12, 2020

Addresses #51

System.Nix.Nar changes its API - the main functions become roughly (not exactly)

  • buildNarIO :: FilePath -> Handle -> IO () Create a NAR from a regular filesystem object, stream it out on the Handle.
  • unpackNarIO :: Handle -> FilePath -> IO () Recreate filesystem object from a NAR file accessed by the Handle

The types Nar and FileSystemObject are no longer parts of the external API, although they still exist and help the implementation somewhat. Removing FileSystemObject was necessary to let NAR construction/consumption work in constant space, since parsing one to completion implies holding it all in memory. In the future we could bring back this return type by stripping out the files themselves. And it would certainly be useful to have that as a parse result, so that hnix-store could analyze the spine of the Nar.

Test tests all pass with +RTS -M10m (limiting heap size to 10Mb), and several of them produce NARs larger than 100Mb. So, we have streaming. There is also a test that packs/unpacks a directory with 1000 files into a NAR and ensures that we do not hold onto file descriptors for longer than needed (as #51 discovered for master).

Copy link
Member

@sorki sorki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also seeing files like nix-store-core/bigfile'_hnix.nar created in my git repo, tried adding setCurrentDirectory just after withTempDir but that makes stuff worse.

👍 overall!

nar <- localPackNar narEffectsIO bigFileName
BSL.writeFile narFileName . runPut . put $ nar
-- nar <- localPackNar narEffectsIO bigFileName
-- BSL.writeFile narFileName . runPut . putNar $ nar
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leftover

Right _ ->
bracket (return ()) (\_ -> P.runCommand "rm -rf testfile nixstorenar.nar hnix.nar") $ \_ -> do
Right _ -> Temp.withSystemTempDirectory "hnix-store" $ \baseDir -> do
-- bracket (return ()) (\_ -> cleanup) $ \_ -> do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^


run = do
filesPrecount <- countProcessFiles
-- nar <- localPackNar narEffectsIO narFile
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover

@imalsogreg imalsogreg marked this pull request as ready for review March 14, 2020 15:16
@imalsogreg
Copy link
Collaborator Author

Ugh - for expectation setting, I'm less confident now that the streaming is working as well as I thought. Limiting the RTS to 10M, I can easily get tests to fail by NARing files > 10M. Still working on it...

@imalsogreg
Copy link
Collaborator Author

@sorki @shlevy @domenkozar this is ready for review, if you have time to give it a look. I'm happy to polish it further. Quickie view of how I'm testing:

cabal build test-suite:format-tests --enable-profiling --ghc-options="-fprof-auto -rtsopts"
../dist-newstyle/build/x86_64-linux/ghc-8.6.5/hnix-store-core-0.2.0.0/t/format-tests/build/format-tests/format-tests +RTS -T -M10m -lp

@domenkozar I'm especially interested in seeing if this branch solves the issues you were seeing, if you can point that project at this branch and adapt for the changed API.

@domenkozar
Copy link
Contributor

@imalsogreg great! I'll try to revive the branch using hnix-store-core and see if it works.

@domenkozar
Copy link
Contributor

@imalsogreg thanks again for this awesome work.

I'm a bit behind on my reviews, will try my best to test this soon.

@imalsogreg
Copy link
Collaborator Author

Thanks @domenkozar, no rush :)

Copy link
Member

@shlevy shlevy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't reviewed the whole thing, but my comments so far have been addressed.

@@ -0,0 +1,97 @@
-- |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

@sorki
Copy link
Member

sorki commented May 9, 2020

I've realized that addToStore has unused p(ath)filter function and repair flag - do you think you can add that as well?

Path filter has a wrong type of (StorePath -> Bool) which should be (FilePath -> Bool) and I'll change that right away.

Looks like repair flag is only used for local store so that can be dropped for now I think.

@imalsogreg
Copy link
Collaborator Author

@sorki any chance your comment was meant for another PR? @domenkozar any luck with your test case?

@sorki
Copy link
Member

sorki commented May 11, 2020

@imalsogreg it was meant for this one. It is related to storepath and addToStore though.

@domenkozar
Copy link
Contributor

@imalsogreg

I get the following compilation errors on LTS-15.14:

hnix-store-core     >                                                                
hnix-store-core     > /run/user/499/stack-9a8eda2a88b9b441/hnix-store-core-0.3.0.0/src/System/Nix/Internal/Nar/Parser.hs:375:13: error:
hnix-store-core     >     • Couldn't match expected type ‘Either                     
hnix-store-core     >                                       (Algebra.Graph.AdjacencyMap.Algorithm.Cycle
hnix-store-core     >                                          (Graph.ToVertex (Graph.Graph FilePath)))
hnix-store-core     >                                       [Graph.ToVertex (Graph.Graph FilePath)]’
hnix-store-core     >                   with actual type ‘Maybe a0’                  
hnix-store-core     >     • In the pattern: Nothing                                  
hnix-store-core     >       In a case alternative: Nothing -> error "Symlinks form a loop"
hnix-store-core     >       In a stmt of a 'do' block:                               
hnix-store-core     >         case Graph.topSort linkGraph of                        
hnix-store-core     >           Nothing -> error "Symlinks form a loop"              
hnix-store-core     >           Just sortedNodes                                     
hnix-store-core     >             -> let sortedLinks = ... in return $ catMaybes sortedLinks
hnix-store-core     >     |                                                          
hnix-store-core     > 375 |             Nothing          -> error "Symlinks form a loop"
hnix-store-core     >     |             ^^^^^^^                                      
hnix-store-core     >                                                                
hnix-store-core     > /run/user/499/stack-9a8eda2a88b9b441/hnix-store-core-0.3.0.0/src/System/Nix/Internal/Nar/Parser.hs:376:13: error:
hnix-store-core     >     • Couldn't match expected type ‘Either                     
hnix-store-core     >                                       (Algebra.Graph.AdjacencyMap.Algorithm.Cycle
hnix-store-core     >                                          (Graph.ToVertex (Graph.Graph FilePath)))
hnix-store-core     >                                       [Graph.ToVertex (Graph.Graph FilePath)]’
hnix-store-core     >                   with actual type ‘Maybe [FilePath]’          
hnix-store-core     >     • In the pattern: Just sortedNodes                         
hnix-store-core     >       In a case alternative:                                   
hnix-store-core     >           Just sortedNodes                                     
hnix-store-core     >             -> let sortedLinks = flip Map.lookup linkLocations <$> sortedNodes
hnix-store-core     >                in return $ catMaybes sortedLinks               
hnix-store-core     >       In a stmt of a 'do' block:                               
hnix-store-core     >         case Graph.topSort linkGraph of                        
hnix-store-core     >           Nothing -> error "Symlinks form a loop"              
hnix-store-core     >           Just sortedNodes                                     
hnix-store-core     >             -> let sortedLinks = ... in return $ catMaybes sortedLinks
hnix-store-core     >     |                                                          
hnix-store-core     > 376 |             Just sortedNodes ->                          
hnix-store-core     >     |             ^^^^^^^^^^^^^^^^                             

@imalsogreg
Copy link
Collaborator Author

@sorki @shlevy or @domenkozar , seems to be working. I rebased the PR on master and ran the tests again. ✔️ Shall we 🚀 ?

@domenkozar
Copy link
Contributor

Happy to test once I'm back from vacations :)

Copy link
Member

@sorki sorki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀

@Ericson2314
Copy link
Member

FWIW C++ Nix now streams files much better with the latest daemon protocol. I would definitely look to use this improvement to implement that next.

@layus
Copy link
Contributor

layus commented Oct 28, 2020

Bump @domenkozar (not too sure of course, but you should approximately be back from vacations now ;-)

As the core and remote versions of hnix-store live in the same repo, It would make sense to also update hnix-store-remote to work with these changes. I made a quick prototype. Is is supposed to work like that ? https://gist.github.com/layus/bcb1cec3051773f67620c1e8ac189267

We will also have to decide if we want to re-export the Nar datatype, or cleanup some functions in hnix-store-remote that use it.

@domenkozar
Copy link
Contributor

Feel free to merge this, it's going to take some time before I can give it a try.

@imalsogreg imalsogreg merged commit 0adc9d5 into master Nov 7, 2020
@imalsogreg imalsogreg deleted the vigorous-io branch November 7, 2020 22:10
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

Successfully merging this pull request may close these issues.

6 participants