CppCast - GitKraken

Episode Date: July 11, 2019

Rob and Jason are joined by Tyler Ang-Wanek to discuss leveraging C++ in an ElectronJS app like GitKraken. Tyler Ang-Wanek has been developing software professionally for the past 3.5 years. H...e works as a senior developer at Axosoft, on the GitKraken team. His work primarily shifts among developing native node modules for use in GitKraken, architectural work for code and APIs around GitKraken, and developing new features for GitKraken. He is the creator of the node module Node Sentinel File Watcher (NSFW), a native file watcher written for GitKraken that has made its way into Atom and VSCode. One of his major accomplishments includes taking leadership of the open source native node module NodeGit. After much hard work on the NodeGit repo and within the community, Tyler joined the leadership group for LibGit2. News Expressive C++ Template Metaprogramming Bring your C++ Code to the Web Voting results for Meeting C++ 2019 Tyler Ang-Wanek @twwanek Links GitKraken Axosoft GitKraken v6.0: The Fastest GitKraken Ever! Sponsors Backtrace Announcing Visual Studio Extension - Integrated Crash Reporting in 5 Minutes Hosts @robwirving @lefticus

Transcript
Discussion (0)
Starting point is 00:00:00 Episode 206 of CppCast with guest Tyler Angwanek, recorded July 11th, 2019. This episode of CppCast is sponsored by Backtrace, the only cross-platform crash reporting solution that automates the manual effort out of debugging. Get the context you need to resolve crashes in one interface for Linux, Windows, mobile, and gaming platforms. Check out their new Visual Studio extension for C++ and claim your free trial at backtrace.io.cppcast. CppCast is also sponsored by CppCon, the annual week-long face-to-face gathering for the entire C++ community. Come join us in Aurora, Colorado, September 15th to 20th. In this episode, we discuss expressive template metaprogramming. And we talk to Tyler Angwanek from Axosoft. Tyler talks to us about GitKraken and how they're leveraging C++ in by C++ developers.
Starting point is 00:01:33 I'm your host, Rob Irving, joined by my co-host, Jason Turner. Jason, how's it going today? I'm all right, Rob. I'm starting to get thinking about all the conferences coming up now. Yeah. I saw a lot of people on Twitter this week talking about their conference talks getting accepted at CBP con. Yes. I have three accepted.
Starting point is 00:01:53 Yes. Awesome. So I've got, but before I can even think about CBP con, I've got, um, uh, NDC tech town and Kongsberg,
Starting point is 00:02:04 Norway coming up. And then just two weeks after that, then I've got CBP con and then in November I will be going to code dive and Wratzow, although I don't think, uh, that might not be officially announced if I'm speaking or not. Well, actually, no, I'm not on the schedule yet. So they don't have a schedule yet. Um, uh, so I don't know. We'll see what's going to happen exactly there. And yeah, so it's three conferences coming up that I'm thinking about at the moment, three talks to prepare. It's a lot to do.
Starting point is 00:02:33 So I guess we should expect to see a schedule sometime soon with CppCon because they have let all the speakers know. Yeah, I mean... For how long that takes. Yeah, optimizing the schedule is its own thing right because they've got so many talks and then they have to deal with all the conflicts like obviously i can't be scheduled to give all three of my talks at the same time yeah and individual speakers can give requests and say please don't schedule me on these days and times and whatever so it that
Starting point is 00:03:02 is a process in itself but the notifications have been sent so i think they got a 50 submission rate is what bryce said acceptance rate so it was a good turnout for submissions this year yeah okay well the top episode like through the piece of feedback um this was actually in response to a tweet you sent out, Jason, talking about your post-CPPCon class, which is going to be on ConstExpr, right? Yes, some shameless self-promotion for the conference for myself here. Nothing wrong with that.
Starting point is 00:03:33 So it's Taylor responding to your tweet saying, ConstExpr isn't something I've had too much of a chance to play with as I've started converting a C code base to C++. That being said, it's something that talked about a lot on CppCast that I want to learn more about. I'll have to see if I can talk my company into sending me to CppCon, which, yeah, I highly recommend trying to get your company
Starting point is 00:03:54 to send you out to some of these conferences. Yeah, if I can just spend one more minute with the shameless self-promotion aspect of this. I speak to people that come from two different standpoints. I say, well, constexpr lets you do stuff at compile time. And people are like, we don't do anything that can be done at compile time. And after like five minutes of talking with them, I convinced them that
Starting point is 00:04:13 they're wrong. Yes, everyone has stuff that is known at compile time. Or sometimes I mentioned it to people and I give some brief explanation of what can happen. And they immediately like, look at their coworkers and they're like, we know exactly where we're going to start using this yesterday. So everyone has something that can be done at compile time. They are not currently doing a compile time. And if performance is a concern for you, well, if performance is not a concern for you,
Starting point is 00:04:39 you're probably not programming in C++. So if you're concerned about compiled runtime performance do more stuff at compile time come to my class yeah but then on the flip side also just of cbp con here um lots of stuff going on right everyone needs to sign up come to cbp con volunteer their call for volunteers is out and um i am organizing the field trip for cbp con which i don't think i've mentioned on the show yet have i i'm not sure if we've talked about that is there any like details you want to share with that now i may as well conference outing right it's the pre-conference field trip yeah so it's we're going to um casa bonita okay which is known by many people from South Park.
Starting point is 00:05:25 And it is a ridiculous Mexican restaurant. It is a real place. It's not just something on a cartoon. It is not known for having good food. It is known for being an interesting place to take tourists. And I figure lots of people watch South Park, they'd be familiar with it. So we should give that a go and then right across the street from that is an arcade that's got just a ridiculous number of classic arcade games so it's one price get in and it's unlimited gameplay and lunch is included
Starting point is 00:05:58 and um the bus ride from the uh the gay lord and back okay sounds like fun yeah all right yeah yeah definitely plan to okay well we'd love to hear your thoughts about the show you can always reach out to us on facebook twitter or email us at feedback at cpcast.com and don't forget to leave us a review on itunes or subscribe on youtube joining us today is tyler angwanek tyler has been developing software professionally for the past three and a half years. He works as a senior developer at AxoSoft on the GitKraken team. His work primarily shifts among developing native node modules for use in GitKraken, architectural work for code and APIs around GitKraken, and developing new features for it.
Starting point is 00:06:38 He's the creator of the node module Node Sentinel File Watcher, NSFW, a native file watcher written for GitKraken that has made its way into Atom and VS Code. One of his major accomplishments includes taking leadership of the open-source native node module NodeGit. After much hard work on the NodeGit repo and within the community, Tyler joined a leadership group for LibGit2.
Starting point is 00:06:58 Tyler, welcome to the show. Hey, guys. Thank you for having me on. Can you just describe briefly what this NSFW node module does? Yeah, absolutely. So one of the first things that I did working for the GitKraken team is my team lead at the time, he said, you know, we really need to get a file watcher into GitKraken. And the JavaScript around file watching right now just doesn't cut it.
Starting point is 00:07:26 It's too slow when it reacts to file events, and it really just chugs the main event loop in JavaScript and can slow your entire application down when you're responding to file events in the main thread. Especially in a Git repo where there are tons of files, just absolutely tons of files. So anytime that you're checking out or switching branches, any of that stuff, or even pulling, you're going to run into massive file events. So what NSFW does is it is a native file watcher. So it has an implementation
Starting point is 00:08:08 of file watching in Linux and in OSX and in Windows, which uses the operating system provided file watching APIs, runs that on its own thread, and is able to batch those file events into kind of manageable chunks that can be sent back to the main thread and responded to in the UI. So that's like if a file's changed, if its timestamp has changed, like any of those? Okay. As many of those as we could cover. However, I've got to tell you, developing a file watcher for all three operating systems, every operating system is different.
Starting point is 00:08:49 Extremely different. It's amazing what doesn't work in one platform, which works really well in another. What one platform provides, another one won't even provide. For instance, like with Linux, we had to write our own recursive data structure, which would walk the tree, the file tree, and build handles to watch every directory in that tree. Because there's no native recursive file watching provided by Linux. Whereas in OSX and on Windows, you can just set a flag when you're starting the file watcher and it's recursive but don't get me started on mac os because it's it's got its own problems its file system uh doesn't really do nanosecond or i guess sub-second uh time resolution on or it's a it's older file system didn't do
Starting point is 00:09:38 sub-second file resolution for some reason and uh it also likes to uh group file events into like a bit flag or uh yeah and uh they keep coming through so you get like added then you'll get added modified then you'll get added modified delete and you have to either keep track of that or go ask the file system is this true actually what's going on? It's a nightmare. And everyone's got their own way of developing those APIs. Windows is different. Mac is different.
Starting point is 00:10:15 And Linux, it's different. Well, it caught my attention because I used to use QFileWatcher on a project that I was using. And I reached limitations with it. I don't even recall exactly what now, but basically I had to do some sort of workaround, even though I had a cross-platform tool provided to me, because all three operating systems would do things differently. I would run out of file handles on Windows or whatever, you know, like, yeah. Yeah, on Linux in particular, the inotify subsystem,
Starting point is 00:10:44 that has a hard limit for how many file handles that you can actually have or how many file watches that you can have. And that's somewhere in like 500,000, which actually some future work there is I need to go back and implement polling in that particular area, uh, so that we have a fallback mechanism. But for now it seems to have just, it seems to have, uh, done enough work to get the job done. So, uh, there hasn't been too much of a need to go back on that yet. I like the idea that you batch them together. That sounds really helpful for response times and stuff in your gui yes and that's uh one of the major advantages of using nsfw uh there are some actually really powerful file watchers written for node using nodes apis one of them is chocodile that would be my major competitor uh chocodile is mostly written in JavaScript. However, they acknowledge that Mac OS has the worst file watching system.
Starting point is 00:11:49 So they have their own native module developed for watching files in OS X. But they actually have more features than we have, but their performance suffers in comparison to what we have and since performance is often what we want in a gui application we're going with ours even with a few less features because we can cover whatever we're missing and and uh choke at our in javascript pretty easily right okay well we'll start digging more into the the work you do on get cracking uh but we got a couple news articles to discuss first. Feel free to comment on any of these, Tyler, okay? Okay.
Starting point is 00:12:29 Okay, so this first one is a post on the Fluent C++ blog by Jonathan Bakura, and this was expressive C++ template metaprogramming. And I really love this article because I often find template metaprogramming to be very difficult to read through. And he goes through an example of how you can break it up and make it a lot more readable while still being, you know, very powerful TMP code. Yeah. I have to. Oh, sorry. Go ahead, please.
Starting point is 00:13:03 I was actually very interested in an article um i i like what i've always wanted to get a little deeper into template metaprogramming we do code generation and node get uh to generate c++ to uh wrap a lib get which is a c library and export that functionality in a javascript and lot of that is written in a JavaScript templating library, somewhat similar to handlebars. And I would love to remove some of that in favor of template metaprogramming. So you have a JavaScript templating library that is generating C++ code? Yes. Okay. Wow. I haven've heard that one before right
Starting point is 00:13:47 i don't think we have actually no yeah it's fascinating but uh the art yeah it really i liked uh his approach it it really helps kind of see uh or get you like thinking about okay what does this mean because when you first see it it's like, well, how do I read this? How do I get better at template metaprogramming? How do I write it more fluently? I think I'm slightly ashamed to admit that the first example, I'm like, oh, yeah, I totally know what that does. I'm not as up to speed as you, I'm sure. I'm like, wait, that's not what I was supposed to say at this point.
Starting point is 00:14:23 But he actually does a great job of explaining what Void T does. And to be fair, Void T does feel a little bit like a black box to me. So I like how he renamed it later. But since I know Jonathan listens to this podcast, I'll point out, I don't think he actually explained Sphenae anywhere. Not in detail, no. I don't think so. And I think that's kind of an important piece of this. Like, why does this whole thing work at all?
Starting point is 00:14:53 And it's because of the magic of Sphenae. Yeah. And the one thing I'll point out, even if you are familiar with template metaprogramming and you can read that initial example and know what it's doing the way you do jason i mean i feel like his suggestions are worth applying anyway because it gets you more reusability the way he breaks things apart right yeah yeah absolutely i've been uh down at his very bottom example there's like template type names finally have some of them have like meaningful names type name attempt class expression right right it's one thing i try to convince my students of like if you're writing a template we're so used to seeing template type name t template type name
Starting point is 00:15:36 you give them names like if all of our variables were named IJK, like, right. Yeah. Okay. Uh, next article we have is bring your C plus plus code to the web. And this is on the coding tidbit blog. And it's all about, um,
Starting point is 00:15:56 getting started with, uh, web assembly using Epscripten. And I thought it was a pretty good kind of intro, kind of get your hello world running and telling you what the steps are you need to do to get it set up on windows using a WSL. If you don't have a Linux box and yeah, I mean it is pretty basic,
Starting point is 00:16:16 but I thought it was a good intro. I feel like Tyler should have something to say about this article because it seems more than his wheelhouse here. So we don't do enough with Wasm yet, and it's partly because there are some performance concerns when you cross that barrier from JavaScript to the WebAssembly transferring data. I know that they're kind of being processed by V8 at the same time, but there's just a little bit of
Starting point is 00:16:43 latency when you jump into Wasm from JavaScript. At least a friend of mine who I think is part of the TypeScript Arizona meetup, he actually was giving a demo on TypeScript where you can directly compile TypeScript to WebAssembly now. Wow. Yeah, isn't that crazy?
Starting point is 00:17:10 I'm going to have a lot of tidbits about a totally different side of the community for you guys. But you can compile TypeScript to WebAssembly. And he just kind of wanted to give an example of that but one of the concerns that he was able to demonstrate uh in his talk is is that uh there's it's not there is a latency concern when switching over to wasm so maybe for projects that are uh purely wasm or or as as it improves we'll see less and less of that and another concern that we've had that has prevented us from jumping into LASM is threading support. And I believe threading support's on the way. I believe Chrome has the feature there
Starting point is 00:17:50 ready, but I haven't had time to evaluate how well that works. I can't even imagine if Node doesn't currently natively have threads in it, trying to make something like that multi-thread capable and a giant code base like that
Starting point is 00:18:06 after the fact is so extraordinarily difficult, it would be a huge project. It's actually interesting to are you guys familiar with any of the low level of Node? I am just because I live it.
Starting point is 00:18:22 Tiny bit. Node.js is actually founded on 1C and 1C++ projects. So it is built using V8, which is Chromium's JavaScript interpreter and runtime for JavaScript. And then it's built on top of Libov. And Libov is an event loop library written in C. And it basically manages IO operations like network file operations and all of these things. And it is actually responsible for what you think of as JavaScript and Node as single-threaded. Because the JavaScript itself is running on that one thread, but a lot of IO network, all of that stuff is actually done off of that thread in Libov's thread pool and is recued on the event loop when that information is ready for JavaScript to run with. It's kind of fascinating, but whenever I hear people say that JavaScript isn't multi-threaded or Node javascript doesn't multi-threaded it's or node script uh node js itself isn't multi-threaded i always think about well
Starting point is 00:19:29 sort of there there is actual threading to it but it's not where you think it is right actually go ahead no please go ahead when we get an opportunity to jump into it uh a lot of the work that i do is is native so uh we write c or c++ modules that are able to take advantage of lib of's threading support as well as all of the uh io operations that it provides for node.js which means that we can run uh batched uh io or you know methods or routines on other threads ship ship that back to JavaScript, and just kind of package it back up and hand it back, and the UI can respond to that.
Starting point is 00:20:11 So there's some really cool stuff that you can get into that's not JavaScript and Node.js, which is strange. Right. I just have one comment about this article before we move past it. At the top, the author says that they're using WSL because VirtualBox only supports 32-bit guest OS. I've been using 64-bit guest OSs in VirtualBox for like 10 years. So I went and double-checked to make sure they didn't somehow remove 64-bit support, which they did not. I think it basically, because they rely on the virtual machine extensions and modern CPUs,
Starting point is 00:20:51 I think it basically requires 64-bit host. And so therefore, it just passes the 64-bit. So VirtualBox definitely supports 64-bit guest OSs. It's definitely an option if you can't use WSL when you're following this article. So if you're not on Windows 10 and you want to go with VirtualBox instead of WSL, you definitely can. Yeah, you could use Windows XP for this experiment if you wanted to.
Starting point is 00:21:16 You might have to go back a rev or two in VirtualBox, but it would still work. But don't let my concerns with WebAssembly off-put anyone. If you're listening, it's coming along, and it's going to be the future of web development at some point. It's going to take over just because WebAssembly, once you're in WebAssembly land, is quick. That's something that the web needs.
Starting point is 00:21:46 So the web will become C++ compiled to web assembly running in javascript on a javascript interpreter written in c++ it's possible i don't know it but one of the things that i've always thought is best tool for the job right right and sometimes it's going to be c++ sometimes it's going to be C++. Sometimes it's going to be Rust. Sometimes it's going to be C. It's just going to depend on what you're working on. Right. One more comment about WebAssembly being the future. I know C++ was the first language to kind of get a compiler for WebAssembly,
Starting point is 00:22:19 and now you mentioned that TypeScript apparently can do it. I don't know much about it, but I know Microsoft and the.NET team also has something called Blazor, which is to get C-sharp into WebAssembly, I believe. So I guess the more languages that hop in the WebAssembly pool, the more it'll advance and become a real thing you can use. So the more the merrier. Definitely. Yeah. One thing that I really want to see happen, Firefox is actually ahead of the game when it comes to debugging support for WebAssembly, where you can actually debug source code in Firefox, but you can't debug that source code in Chrome. You can only debug the WebAssembly right now.
Starting point is 00:23:00 So that's another pitfall for Electron users since we're based on Chrome. We don't even have that support yet, which is unfortunate. And then last article we have is, I think it was just a few weeks ago that we mentioned meeting C++ 2019 and how Jens made it so you can now vote for the tracks or vote for the conference talks. That everyone can. Everyone can. Even if you haven't bought a ticket, you can go in and vote. vote for the tracks or vote for the conference talks that everyone can work everyone can even
Starting point is 00:23:25 if you're even if you haven't bought a ticket you can go in and vote and uh he's announced what the first 11 talks uh are going to be based on that voting and these are going to be the talks for the main track and definitely some familiar names here uh bryce adelsstein lelbach is giving two of these talks two of the top 10 yeah yeah uh john called giving one of them uh i know i recognize some of these other names but he's only giving the last names here so i don't recognize all of them yeah uh yositas is an author we've never had him on but he's well known um as well those are the main names I recognize immediately. And I'm assuming that's John Kalb. I'm assuming so. Not some other Kalb.
Starting point is 00:24:10 Right. Edelstein Lelbach? Pretty sure that's Bryce. Yeah, so Bryce giving a talk, one on modules are coming, another on the C++20 synchronization library. John Kalb giving a talk on modern template techniques. It'll be really interesting, yeah.
Starting point is 00:24:27 I'm looking at that coroutines talk. I'm actually pretty interested in coroutines. We had some support for coroutines land in JavaScript through generators, which build iterators with that yield keyword that allows you to pass values out and receive values from whoever's driving your iteration. And with libraries or with that power, we've actually been able to get some odd threading support or to split up our main thread in JavaScript using coroutines, almost like a threading library. I'd like to see what you can do or what you can dream up
Starting point is 00:25:07 in C++ with coroutines. It does sound like in the last episode we discussed, there's still some questions about the C++ coroutines keywords and such. We'll see what exactly shakes out in Cologne, which is what? What is that? This week?
Starting point is 00:25:23 Next week. Okay. Okay, well we already made a couple references to the project you work on. Tyler, can you tell us more about GitKraken? Yeah, GitKraken is an electron application that
Starting point is 00:25:37 tries to make Git easy. Git can be pretty opaque. We've all heard about the directed acyclic tree before, about the directed acyclic tree before, or the directed acyclic graph from XKCD. But really, it is hard to work with Git. There's a lot of command line things that you need to learn.
Starting point is 00:25:59 There's a lot of hidden magic when it's in the command line. And even if you're a power user that uses the command line, you still have tools for displaying the graph and navigating commits, maybe like Maggot. And we think that we can simplify it a lot with a really great graph to show you how your commits work together. Try to simplify that. And yeah, we're also kind of opinionated. There are some things that we don't support
Starting point is 00:26:35 specifically because we think that they're not great concepts in Git. One of them, and I don't know if anyone wants to hear this, is I think that a headless state in Git is a bad state to be in in general. Temporary branches are way more powerful. And temporary branches are a better state to be in because there's more Git operations supported in a temporary branch than there are in a headless state. Okay. So, you know, we have opinions. But I think we make a really great tool. It's fast and easy.
Starting point is 00:27:10 So do you disallow getting into a headless state from the GitKraken perspective? We don't. We don't typically. We don't expose the ability to get into it, but, of course, we support it. Right. So if you were in a headless state, we work just as well as the command line would. We just don't support getting into it very easily. So if the user does something on the command line, you'll reflect that accurately. Absolutely. So we're pretty close to one-to-one with what you
Starting point is 00:27:36 can do in the CLI. It's just some of the things we like to hide or abstract from users because not always the strongest things, but that's not really even a critique of Git. That's more of just a, what's important when you're working with Git? And that's, you know, it's paying attention to your commits. It's paying attention to your diffs and it's seeing other people's work and uh being able to cooperate uh so we want to make that part the easiest okay so you mentioned that get kraken is an electron js app and we were uh you know asked to you know get one of you uh get kraken developers on the show because someone saw a blog article who's a listener of the show saying hey these guys are writing an electron js app and starting to move into c plus plot so can you maybe start off by telling our listeners a little bit more about what electron js is yeah so uh
Starting point is 00:28:35 it's actually i love explaining electron because first uh the community was like i love javascript you know uh google's doing great things with j. So let's take JavaScript from Google Chrome, get rid of the browser, right? Get rid of the browser and build a server-side JavaScript, right? And then at some point, someone was like, well, I love Node.js. I love the server-side JavaScript. Why don't we give it a UI
Starting point is 00:28:59 that you can work with the server-side JavaScript with? And they're like, I know a perfect tool for that. Let's get the Chromium web browser. And that's the best explanation I have for Electron, is they built server-side JavaScript, and then they recoupled the Chromium experience with the JavaScript experience again, just in a different format it's uh it's fascinating
Starting point is 00:29:28 okay so essentially if you're running electron js app you're kind of running a somewhat stripped down version of chrome yeah you you definitely have chromium running on your machine uh and you have several you have a lot of parts of it but it is stripped down there's a lot of parts of it, but it is stripped down. There's a lot of stuff in Chrome that doesn't make it into Electron. Some of the benefits, though, of doing that, not just to, you know, it is kind of wacky to think about how it came about, and a lot of programming, I think, has a great story, right? But with Electron, some of the benefits are that it has a lot of awesome cross-platform support because it's based on Chrome. So there's a lot of libraries and functionality that's built into Electron that you need in most desktop applications anyway.
Starting point is 00:30:19 So it comes with a big toolbox. And, of course, that's also a valid criticism of Electron is it does come with a big toolbox. So it course, that's also a valid criticism of Electron, is it does come with a big toolbox. So it's a bigger application to begin with. But you can just render any CSS, HTML, whatever in there? Yeah, any HTML, any CSS, and you have a lot of the tool set that you get with Chrome, and you have a deeper level of control with Chrome, but you also have all of the power of Node.js and all of its ability to interact with the operating system in ways that, you know, regular websites can't operate with the operating system. Intentionally. Intentionally, right. That's fair enough. I want to interrupt the discussion for just a moment to bring you a word from our sponsors.
Starting point is 00:31:07 Backtrace is the only cross-platform crash and exception reporting solution that automates all the manual work needed to capture, symbolicate, dedupe, classify, prioritize, and investigate crashes in one interface. Backtrace customers reduce engineering team time spent on figuring out what crashed, why, and whether it even matters by half or more. At the time of error, Backtrace jumps into action, capturing detailed dumps of app environmental state. It then analyzes process memory and executable code to classify errors and highlight important signals such as heap corruption, malware, and much more. Whether you work on Linux, Windows, mobile, or gaming platforms, Backtrace can take pain out of crash handling. Check out their new Visual Studio extension for C++ developers companies like fastly amazon and comcast use backtrace to improve software stability it's free to try minutes to set up with no commitment necessary check them out at backtrace.io cpp cast okay so uh how exactly are you starting to leverage more C++
Starting point is 00:32:05 and maybe go over why you started making that move? So GitKraken, and I think this may surprise you, but a lot of GitKraken is actually written in C++ right now. And we talked briefly about NodeGit, which is that JavaScript library that generates a bunch of C++ to wrap that C library. That's a lot of, like, I mean, that's probably, I mean, there's a lot of larger companies out there
Starting point is 00:32:39 that are going to laugh at this, but it's probably 150,000 to 200,000 lines of code, right, that we generate. Generated code. That's a fair bit of generated codeated code. That's a fair bit of generated code. It's a fair bit of generated code. Libgit 2 is a big project, and we like to re-export as much of that as we can. And I'm actually just going to prefix this. Many people might be wondering why we don't use something like FFI
Starting point is 00:33:02 for integrating with a C library. And that actually something like FFI for integrating with like a C library. And that actually exists. FFI does exist. But FFI also has performance concerns. And Node FFI project runs slower than if it was compiled, if it was just like a regular compiled binary, or if it was a native add-on for node um so i'm only vaguely familiar with ffi can you explain that for a moment foreign function interface and so if you have a library that's compiled it can export certain it can export symbols that are uh and it can export the symbols and foreign function interface is a way for you to interact with that library, even though it wasn't written in the language that you're using.
Starting point is 00:33:51 It wasn't compiled for whatever thing that you're working on, where you're able to kind of call into that and hook up to some of those functions. For Node FFI, actually, one of the tougher things is JavaScript is a garbage collected language, and the FFI package that would help you compile that is, I don't think, adequate for a complicated library like LibKit 2, which has its own methods for freeing structs, and the way that Node FFI ties those structs into the garbage collection system would not be correct. There's caching mechanisms going on in the background.
Starting point is 00:34:31 So how do we get the C++? Well, we had C++ in our application to begin with. And we started with all of that generated code providing the ability to call C code from libgit2. And we wrote a lot of JavaScript, which was just calling out these functions. And these functions are asynchronous, mind you. So we talked earlier about an event loop in Node.js and how libof does have some threading support with it, but it's kind of hand-waved away to the JavaScript user. So you're writing...
Starting point is 00:35:11 So the lib get has a bunch of these... Node get exports lib get functions as async functions if they were to do, like, I-O. So you're going to check out or push. You know, that's a network operation or a file operation that's going to be blocking somewhere, right? So that will be run on a thread in Nugget. And you'll have kind of a handle to that or a callback in the event loop where you'll get the result of that operation later in the event loop. And then you can continue working.
Starting point is 00:35:46 So we had all this generated code, and this generated code kind of, when you have that many asynchronous functions, and you're writing tons of business logic for doing Git operations, and you only have one thread to process events for the event loop, you tend to bottleneck the event loop. Okay. And you bottleneck it in a big way. And I think one of the best examples for this is we had another project which was doing a deep dive on a folder structure to see where all of your Git repositories are, right? So we can display what git repositories a user might have. So originally, we had a JavaScript implementation of this. And what's interesting is that you would asynchronously ask for what directories or what's in a directory. And then you would get a result
Starting point is 00:36:43 back from that. And you go over that. And you make calls for each one of directory? And then you would get a result back from that, and you'd go over that. And you'd make calls for each one of these, and then you would asynchronously go dive into that, right? Well, say something else is happening. So now you scan for directories, you get that list back, right? And something else is happening. So instead of immediately going and checking what things are directories and what those directories have, you wait. Someone else is processing right now in the main event loop. So you can't respond to that, and you can't continue the algorithm.
Starting point is 00:37:14 Now, it's still responsive, right? But that's paused because the user is doing something else or there's something with higher priority happening in the event loop. So that algorithm, which is just trying to search through directories, is actually not... If you looked at the time it took when it was actually processing, it's about the same speed as it is synchronous. But if you factor in all the other things that are happening in the application, it's so much longer because it's had all these pausing points. It's paused so many times.
Starting point is 00:37:45 It's almost like thrashing a CPU. It gets paused to allow other things to happen, and the overall process of delivering the results of the full directory walk is way slower. And that was something that we had identified early on. So we had always tried to tackle certain problems that we want to be responsive, but take up too much time to be processed in JavaScript. And we've always tried to move those things into C++. So coming back to NodeGate, right? We have a lot of JavaScript that's doing similar things to the directory walk.
Starting point is 00:38:26 So we're going to go get a list of all the commits, right? But that in lib gets exported as a walk on the SHAs. So it's going to give you a bunch of SHAs back in a rev walk. And then you're going to have to go look up all the commit objects for those shots, right? So you do that 2,000 times, right? But say you're also looking for references and trying to figure out what references are tags, what references are branches. And you've just got this massive asynchronous. You've got two massive asynchronous operations that are kind of contending for the same thread's attention to complete their goal.
Starting point is 00:39:06 But they're both being slowed down because they're synchronizing in the main thread. So for us, what I wanted to do is we have libgit, we have node-git, and we have a feature in node-git which allows us to write C++, which can just be tossed into the generated code uh wherever we choose and can kind of become part of uh the compiled side of get kraken and so say we take that commit walk and we want to look at all these commits we can write one method in c++ that runs on a separate thread, and on that separate thread, or in the thread pool rather, in the thread pool it's going to
Starting point is 00:39:50 do the rev walk, look up all the commits, and then give you all the commits back in one shot. So now how much async work you did is you called one function, and you had one callback and it had the results or it didn't have the results. Of course, if there's an error, right? But that allows the main thread to do other things or to coordinate other work. And so for us, C++ is almost like the obvious choice because we already have such tight integration of C and C++ that we might as
Starting point is 00:40:27 well expand in that territory when it makes sense. And the nice thing about being an Electron app is Electron provides a lot of awesome utilities that just make programming super easy and flexible. And it's this really cool hybrid approach that we have right now or that we're expanding on where we can write things that need to be performant or quick or non-interfering with the main thread on our thread pool. And when we need to do things that the user sees, when we need to do just the small touch-ups to that data before the user sees it or interacts with it, we can handle that in JavaScript and show that in HTML CSS and work with that in a really clean way. But that's kind of what the driving force for C++ and GitKraken is, is that Node has native support for C++. And it has, it's not any other
Starting point is 00:41:29 language that's like directly supported by Node.js besides JavaScript and C++. And it's just because the JavaScript engine that's running in Node.js is V8, and's all c++ and uh lib of which is you know it's c but it's compiled by you know c++ compiler it's uh you have you have uh it's already like a great place it's already ready for it right it's just kind of saying hey this is the right move so it kind of i mean hearing what you're talking about sounds like a complicated build process to me. You've got generated C++ code, you have to compile Node modules, and you've got the JavaScript,
Starting point is 00:42:12 and they're like, is this difficult to manage all of these pieces? So we have kind of like a Unix approach to a lot of this, and that makes it easy. So GitKraken with its JavaScript primarily is all by itself. It's primarily focused on getting Electron in and getting JavaScript working. We have NodeGit, which is actually a completely separate project that compiles on CI, ships over there, does its own thing. And we don't have to worry about, well, I do, actually. I manage a lot of things, but I guess I kind of shield.
Starting point is 00:42:51 I'm kind of like a barrier. A lot of our programmers can work in JavaScript where there's a lot of, it can be really easy to work in JavaScript, and that's nice. But we also have just this other area um for compiling that but when you're building uh locally it's occasionally you'll come up with oh we're switching compilers so everyone needs to you know update from uh vs 2012 to 2015 before you can uh rebuild get kraken because somewhere deep down, one of our packages now uses 2015 and not 2012.
Starting point is 00:43:30 Or we switched from Clang back to GCC, surprisingly. That was because our CI servers, the version of Clang available on them was kind of causing crashes. However it was being compiled, it was crashing in Linux, and that was unfortunate. Right. But you've got to make do with what you have. So, yeah, long story short, yeah, it can be complicated,
Starting point is 00:43:59 but I think we've done a lot to manage the complications and to isolate each system into something that compiles by itself and can just kind of integrate seamlessly. So do you ever at any point have your JavaScript developers be like, this thing that I'm working on is just too darn slow. I need to toss it over to the C++ developers or vice versa. Have the C++ people be like, you know, it would make way more sense than throw it over the fence to the JavaScript people.
Starting point is 00:44:27 So we're trying not to. So I may have given off the impression that we have totally distinct. I am trying to ramp up everyone to not only be JavaScript, but to be involved in the C++ as well. So they can all make a decision. Yes. We don't. We want to be like properly polygl++ as well. So they can all make a decision. Yes. We want to be properly polyglot, and that's hard, especially C++ is a big language to learn.
Starting point is 00:44:55 There are a lot of intricacies, and it's hard to be an expert, and I'm not one, right? And there's just so much out there, and it continues to improve and expand. And so, and unfortunately, due to just restraints that are constraints that we might have, we don't get to use some of the newer C++ features just for, you know, we want to target like a minimum build for like Linux, say, right? So we may not be able to get to C++ 17 or 20 anytime soon. So yeah, we're trying to get everyone to be able to switch back and forth. And I think I was really happy with the performance work that we did for GitKraken on our last
Starting point is 00:45:41 release because I saw some people that were just, they had largely remained JavaScript developers for a long time, even though we had the C++, and I saw them say, you know what, this is what we need to do to make it performant. And they really stepped up,
Starting point is 00:45:59 and they jumped into that, and they learned what they needed to learn, and they improved some of our algorithms and get cracking and that that's awesome and so i hope that we can just keep on that trajectory that's very cool so the question i had is um it sounds like you've been working on this for a while and you now have a nice mix of both javascript and c++ and you're trying to ramp up the C++ even more. If you were starting a brand new app and using ElectronJS, how much effort does it take
Starting point is 00:46:33 to start leveraging C++? So it's actually not too bad because, well, let's prefix this. Documentation in Node.jip could be way better. And are you guys familiar with JIP? Generate Your Project? That's right, Generate Your Project. It was a Google-backed kind of like make file system where you could – it generates a project, right? It can build it for Visual Studio or
Starting point is 00:47:07 gosh, why am I blanking on this? Xcode. Or it could generate make files. Now that's been replaced in Google by Ninja, right? So they're using Ninja for Chrome now. And I wish we could use Ninja. But we're still stuck on JIP and the NodeLand. But grievances aside of documentation and JIP, JIP is like a first, NodeJIP
Starting point is 00:47:31 is a first class citizen. And what NodeJIP does is it allows you to write binding files. And binding files are just a description of what C++ files have to be compiled and how they need to be compiled. And that also helps link it with V8 and libof and get it to be a dynamic library that's ready to be loaded by JavaScript.
Starting point is 00:47:54 So there's actually really decent support to build C++ right alongside your JavaScript. And at a small talk that I did for an Electron meetup in California, one of the takeaways that I had was if I were to start a new Electron project, I would try to have a JavaScript source folder, but I would also try to have a C++ source folder where just
Starting point is 00:48:24 right there in in your electron app you have the means to just start to write a new feature right there not another project uh as part of just get cracking or that electron app right so even if you don't have immediate use for it you would start with it from the beginning i would at least leave space for it right um so i i would make sure that there's a nice little cozy corner for when we do need it and i i think as you grow as a desktop application you have to think um you are a desktop developer and a desktop developer uh has so many more resources than just javascript at at in front of them. And there's tons of other things that you can do at the operating system level
Starting point is 00:49:10 or at the library level that other developers have open sourced that would be at your fingertips if you kind of opened the door and jumped into that. Is there a good tooling story with evaluating the performance of some of these changes? Like are you able to really measure when you switch over some component or feature from JavaScript to C++ how much it improves? Yeah, so one of the early things that we worked on was migrating. I talked about like reading references earlier and so we just did like a small refactor of of that uh we have timing systems in the javascript which uh allow you to see like how long did a function take to run so uh even you know across the asynchronous nature of it uh so we would time
Starting point is 00:49:59 these functions there and then we would time them after they've been written in C++. And what we care about is how long does it take to get the results. We don't care how long it takes to run the code in C++. We care how long does it take to go out to C++ land and come back to JavaScript and be responsive. And so that was the metric that we were looking at. And with that metric and refreshing references, we saw like a two to four times improvement on a cold start and an eight times improvement when GitKraken's already running, and so what that means is just when GitKraken's booting up,
Starting point is 00:50:36 there's a lot of stuff going on. There's a lot of threads involved in getting GitKraken started initially, and, you know, when you have a lot of threads, it's going to slow down in other ways, right? But once it's started and up and running, it doubles the performance of the cold start, which is really cool. Okay, so while you're trying to make sure that you've got this, you know, round trip time that you expect, it sounds like having a reproducible performance test suite would be relatively difficult. Yes, actually. So we have been paying attention to one of our other Electron app developers, Microsoft, who is building VS Code. And VS Code, I think, if you really look
Starting point is 00:51:22 at it, it's one of the fastest Electron apps out there. It really is. They've done great work optimizing it. And the VP of product here, Hamid, went out to a conference where Microsoft was talking. And one of the talks that they gave is how did they optimize perform or for performance and also how did they measure performance and one of the things that they mentioned uh is they have a terrible laptop and it is connected to ci and whenever a new build comes out and it's a it's just an awful old laptop might have like a hard drive uh that you know low ram terrible cpu but they run uh vs code and check the startup time of vs code uh 10 times on every build and they need they make
Starting point is 00:52:19 sure that at least one of the startups meets uh their expectations at least one so at least one so at least one of the startups of of of these startups on this awful awful terrible laptop has to meet certain performance expectations and so we have an old laptop now that's hooked up to our ci that on new builds can check that same condition and tell us are we still starting up quickly, which was one of the major things that we were focusing on for performance last. I've never heard of that technique before. I'm going to have to...
Starting point is 00:52:56 I mean, it sounds slightly fragile because eventually that old laptop, it's going to die. Fair. There's always more. There's always other old laptops. can actually i've got two every year a new laptop is old yes if if you need any extras just let me know i will mail them to you so yeah it is an interesting way to measure performance but um it's also you know it it gives um it actually gives valid feedback it it is actually really good feedback to see that on this old system it's
Starting point is 00:53:33 starting up that fast and if it's starting up that fast on an old system it's almost guaranteed that it's going to start up fast on a newer system and so that's why uh i think the metric, while strange, is good. And is it then with a known repository or something? Yes, it's always the same repository. The system is always running the same things. It does nothing else except wait for a request to test. Right. Yeah.
Starting point is 00:54:02 That's kind of cool. I didn't think about that. It doesn't work in the realm of cloud computing. No, no, I wouldn't say so at all. But for desktop development, I think it's not too bad. Now, that's startup time. But we still, I don't think we have a great infrastructure for automatically testing other aspects of the performance of the application. But a lot of the things that make the app feel snappy are also things that make the app start up fast,
Starting point is 00:54:34 which is a lot to do with reading data and getting data ready to display. And so they're kind of intermixed. So if one's fast, typically the other remains fast and snappy. So I can't wait for the day when that's not true, and we've got to think harder. But it'll come. Okay. It sounds like there really are a lot of ElectronJS apps out there
Starting point is 00:54:59 that developers are using, like GetKraken, which you might be using for your source control, VS Code, which has become a very popular editor. I think Slack is another ElectronJS app that a lot of developers use. Yeah, but Slack gets a lot of flack for using 16 gigs of RAM while you're in a chat session. Is that a feature of ElectronJS? It doesn't have to be.
Starting point is 00:55:22 It doesn't have to be, okay. But it is easy to get there if you're not careful. Though I'll tell you, because we use some C and C++ ourselves, we always have the option to foot gun ourselves with memory management. I've done it. We've all done it, right? Right. It happens.
Starting point is 00:55:46 But with JavaScript, it's harder to control. And so in some respects, you have to be really careful about, because it's garbage collected. You don't want to get the garbage collector in a state where it's like, well, we're looking at that guy, looking at this guy, looking at that guy, and now we can't. Now we're in a cycle, and guess what? We're around at that guy, looking at this guy, looking at that guy, and now we're in a cycle. And guess what?
Starting point is 00:56:06 We're around to stay. So, yeah, it can get memory intensive, but we try to pay attention to that. Well, it's been great having you on the show today, Tyler. Yeah, thank you guys so much for having me. Yeah, thanks for joining us. Thanks so much for listening in as we chat about C++. We'd love to hear what you think of the podcast. Please let us know if we're discussing the stuff you're interested in,
Starting point is 00:56:27 or if you have a suggestion for a topic, we'd love to hear about that too. You can email all your thoughts to feedback at cppcast.com. We'd also appreciate if you can like CppCast on Facebook and follow CppCast on Twitter. You can also follow me at Rob W. Irving and Jason at Lefticus on Twitter. We'd also like to thank all our patrons who help support the show through Patreon. If you'd like to support us on Patreon, you can do so at patreon.com slash cppcast. And of course, you can find all that info and the show notes on the podcast website at cppcast.com. Theme music for this episode is provided by podcastthemes.com.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.