-
Notifications
You must be signed in to change notification settings - Fork 408
🎬 nodegit 2: The Revenge of nodegit! 😱 #524
Conversation
This replaces the shelling out version (which was writing to the index) with a read-only implementation, allowing us to parallelize this operation and improve performance 🐎
Even if the speed improvements weren't noticeable, I'd say that this alone ☝️ justifies using nodegit for status. Having to close Atom to do a |
|
Hm, in certain repos we're seeing |
|
Heyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 👋 🚶 📖 So I have a few specific bits of feedback and one more general. It's entirely possible I don't have all the context of this PR, in which case feel free to tell me! 💖 Specific first 🎯
That's true, but that comes with a downside. This is especially important in repositories with lots of files.
Because of that we specifically steered Desktop Windows away from using libgit2 for status.
(If this line was a throwaway, then feel free to ignore me.) If the GitHub package is always holding a lock on the index, that seems to indicate a bigger problem than just holding it while getting status.
More generally 🌏 I wanna make sure we're thinking about this strategically (puts on his mr. manager hat 🎩). The Atom and Desktop teams met last summer to talk about our shared approach to git, and one of the reasons we deliberately chose not to use libgit2 is because it's unsupported/poorly supported. No one is investing in it. That's still true. Git interaction is a shared concern across both the Atom and Desktop teams. In the next year we should work to share more of our git code. Branching (lol) our approach to git by using libgit2 moves us away from this goal. |
|
Thanks for the input, @joshaber!
Right. Although looking at recent waterfalls, the time of Furthermore, since we group reads and writes and only let reads run in parallel,
Yeah, this is very compelling in general. Do you think it's still safe to use for basic read operations (like looking up commits/remotes/etc) which is what we'd like to use it for? We don't want to use it for any write operations (unless you include
Super valid concern, although I think the plan is to phase out 32-bit Atom builds completely in the nearish future.
I agree in general. My impression was that we landed on this because it looked like the use cases would be very similar and we'd otherwise be duplicating work. However, I'm not 100% sure we should force that if the current strategy isn't meeting the needs of one team or another (though I can certainly see the argument that we can spend more time working together to resolve the issues). |
Semi-related tangent - VSCode made some changes to their Git operations in a recent update and they're causing the exact same issue for us when we're in Desktop:TNG. It really feels like the same behaviour you're describing here with |
|
@shiftkey How are you avoiding that problem in TNG? Just not running status very much? |
|
@BinaryMuse we don't do anything when the application is in the background. That behaviour might change in the future, but it's Good Enough For Now™. |
It's been a while since I've looked into these, but here's some previous anecdotes involving both read and write operations:
And while dropping support for 32-bit applications is a way to workaround address space limits, what I wanted to call out here was a couple of things:
Another footnote to this - when we caught wind of Microsoft moving away from libgit2 in the middle of last year, we sat down with them to understand more of this situation. The discussions there were also very similar to what we've been talking about here, and they were really unhappy with the behaviour differences they stumbled upon between |
|
I checked out the source for status in the git source and, if I'm reading this correctly, If we could find a way to make that work, we could even run Disabling the status call when Atom/Desktop aren't in the foreground is a pretty reasonable workaround, though. |
This makes me sad, I really like the idea of libgit2 😢 As much as I like the UNIX-y philosophy of using stdin and stdout as a universal interprocess communication channel, shelling out will always feel "heavy" to me. I hadn't thought about address space limitations, though, and being guaranteed to reclaim memory from repository operations is a pretty big upside, especially as RAM-hungry as Electron apps already have a reputation of being. Another alternative @BinaryMuse brought up a while ago that I liked was to implement selected git functionality directly with Node I/O, especially for the less involved and more stable operations like "reading blobs" or "dereferencing HEAD." We could even add tests to git-kitchen-sink to verify that our implementations stay consistent with the bundled git binaries. That'd lessen the burden on our command queue and drop the latency on those operations (although the easy-to-port ones aren't our most expensive, of course). With the performance measurement tooling we'll have some data to back up the most worthwhile candidates to port, too 🔬 |
…-revenge-of-nodegit
|
Okay, we've chatted with multiple people, and we've decided to put the "no" in "nodegit." We may experiment with doing certain operations (like reading blobs, if they exist) with raw JS, but for now we'll do with the improvements we've made to queue parallelization and to |

So we have some slowness going on. A lot of this is due to queueing up Git operations and making sure writes get executed alone. This is exacerbated by the fact that we're shelling out for all operations.
We used nodegit in the past, but stopped because it was awful crashy for us. The theory was that this was due to write contention, or the fact that we didn't have/didn't use nodegit's threadsafe mode. This PR implements some of the read-only Git commands using nodegit, resulting in significant improvements at a glance:
And these times are during unit tests, so are a bit artificial.
After using this for a while in a real-world scenario and taking a look at the waterfalls, it definitely seems like it's helping, though certain Git commands are still taking a considerable amount of time.