nix-tree icon indicating copy to clipboard operation
nix-tree copied to clipboard

Feature request: Manage gcroots interactively

Open DavHau opened this issue 4 years ago • 3 comments

I have the problem that I have been executing nix builds in many different directories over time and therefore there are tons of result files and corresponding gcroots in /nix/var/nix/gcroots/auto.

I know there is nix-du for gcroot visualization. I have never really used it, but as I understand it, you have to execute the program, pipe it into a renderer, inspect the graph and then execute command manually to free the space. Sounds still quite inconvenient to me.

I have the feeling, a UI like the one of nix-tree would be perfectly suited. It's already possible to inspect individual gcroots via nix-tree. I can, for example execute nix-tree /nix/var/nix/gcroots/auto/0k6bnn1z76mfddabj8b1pmfkvygms6m3 which will show me the tree and closure size of that single gcroot.

It would be nice if I could zoom out one more step and see all my gcroots listed (preferably sorted by closure size). Then I can conveniently scroll through them and hit the delete button on the ones which I'd like to delete.

I'm aware of the fact, that finding out how much space a gcroot can actually free is not trivial, since some of it's dependencies could also be blocked by another root. But I'd guess that the total closure size would already give a good enough estimate.

DavHau avatar May 04 '21 15:05 DavHau

I think this is a great idea! I would use this feature too.

Here's a draft of what I think we can implement:

  • Add a command line flag called --gcroots
  • On this mode, first do something along the lines of nix-store --gc --print-roots | grep -v '/proc/' to figure out the gc roots.

You can pretty much replicate the functionality up until this point in the current state of nix-tree with a command like:

nix-store --gc --print-roots | grep -v '/proc/' | grep -Po '(?<= -> ).*' | xargs -o nix-tree

You can also sort them (with the s shortcut) with either the closure size, or "added size" (see the glossary at README.md).

However, after that, we can implement a few more utilities.

  • nix-tree currently only shows the store paths, however in this case it would be also handy to show the path of gc root too. So maybe we'll just have each gc root take two lines; first line is the path of the symlink, and the second line is the store path.
  • We can have a shortcut to delete (if possible, of course) the symlink. This is actually a bit tricky, because then we need to recalculate a bunch of things (because of the "Added Size" calculation).

But in the end I think this will be a useful feature so I will try to add it.

Let me know if the points above make sense to you, and thanks again for the issue!

utdemir avatar May 04 '21 22:05 utdemir

Also, it seems like visualising all roots surfaces some performance issues. I suspect this is also because of the added size calculation which is quadratic. I'll need to work on that too.

utdemir avatar May 04 '21 22:05 utdemir

nix-tree currently only shows the store paths, however in this case it would be also handy to show the path of gc root too. So maybe we'll just have each gc root take two lines; first line is the path of the symlink, and the second line is the store path.

I think the path of the symlink and the store name (last element of store path) are the most relevant. I'm not interested in the store hash or gcroot hash/path etc. Maybe that can show in the details. Basically like nix-tree does it already, just adding the symlink path.

We can have a shortcut to delete (if possible, of course) the symlink. This is actually a bit tricky, because then we need to recalculate a bunch of things (because of the "Added Size" calculation).

If the added size calculation turns out to be to inefficient to do, then maybe it's just enough to display the closure size of each gcroot, and by deleting the symlink, it just vanishes from the list.

I mean, theoretically, the nicest version of this would be if one would know exactly how much space would be freed and if, when hitting delete, the space would actually be freed immediately, so you won't have to run a garbage collect manually afterwards. That would also bring the benefit to collectively garbage collect. But I'm not sure If the nix provides the right interfaces to do stuff like this.

nix-store --gc --print-roots | grep -v '/proc/' | grep -Po '(?<= -> ).*' | xargs -o nix-tree

If I run this, it will take nix-tree a long time to initialize and afterwards navigation is still quite laggy

DavHau avatar May 05 '21 11:05 DavHau