Building Web Apps like Google with Angular, Bazel, and GCP (Cloud Next '19)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC PLAYING] DANNA KELMER: Hello everyone. Good morning. My name is Danna. I'm a software engineer on the Bazel Team at Google in New York. Today, we are going to talk about problems that certain organizations start to encounter as their company and their projects grow, in particular with-- in relation to build and test times, and then go over the ways in which the build tool Bazel can help alleviate some of those pains. And finish up with a testimonial from the Angular team about how it's been working for them. So why might an organization need Bazel? Certain problems start to arise as your organization grows. Your projects start to grow and the needs of your infrastructure start to suffer with the load that it requires, and in turn, this might affect your-- the development experience of the people at your organization. And in part, this happens because, as you have more developers, they start to make more changes. And more changes means that you need to run all of your tests far more often. So if you wanted to run all of your tests before every submit, that starts to increase as you have more people. The second thing that affects this is as the feature space starts to grow, this obviously increases just the sheer number of tests that need to run. So this is more load that must happen with every change. And the final part is as your project becomes larger, each individual integration test requires a ton of compute power just for a single one. And so it starts to become, very quickly, infeasible to run all of your tests on every submit. So basically, many organizations tend to give up on integration testing. And this means that instead, they'll break up their projects into a number of microservices where each service is responsible for its own set of tests, and then those will run on every submit. And you'll only ever run your substantial integration tests when you attempt to release. So this is an example of a way that you might break up some project. And what this means is that when you're releasing, that's the first time that you're going to encounter problems with the interaction between these different microservices that have been working separately. All right, so what is Bazel? And how is it going to help this problem and enable and empower your organization to run all of these tests as often as possible on every commit? So Bazel is a free and open source automated build and test tool. This tool has been used at Google for nearly the past 15 years to build all of its source code. And I'm going to go over the properties of Bazel that enable this, that enable you to run all of your tests across your entire organization as often as you'd like. So the first property is that Bazel is hermetic. This means that Bazel is aware of all inputs before the build begins. So of course, this includes all of your source files and everything that would need to be built. But this also includes any tool, for example, that would need to be used over the course of the build. And in turn, this hermeticity directly lends itself to Bazel being incremental. And so because Bazel is aware of all inputs, for any change you make, Bazel can very easily calculate the minimal amount of work that needs to be done in order to create your finished build product. And so, if you make a small change, you should expect that the amount of work that Bazel will do will be proportional, that it will be small. So I'm going to demonstrate that. All right. So here's an example. We're starting. We're asking Bazel to build all the tests. And, just to start, we see that everything is fully cached. So this is imagining a scenario that you just did a build, right? We're starting. Everything was already built, and now we're going to make just a small change. So the change is going to be to a single test file. So a test-- a test itself, often nothing depends on that test. So the expectation is that when you make the change to this single test, that only that single test will have to be rebuilt and retested. So here's an example test file. We're going to add an additional assertion to this test to make sure that everything, or that this thing is not null. And then, again, what we're going to do is we're going to ask Bazel to retest everything. But the expectation is that Bazel will be smarter, and it will only rebuild that single test and rerun that single test. So Bazel is working and beautiful. Everything is cached. But we see it executed one out of 174 tests. So that's the one test that we edited. Everything else is still cached. All right. The next property of Bazel is that it's deterministic. So Bazel uses the checksum of all of the inputs to the build in order to determine whether or not they've changed. And what this means then is that Bazel can very safely cache any intermediary build artifacts that it produces. And then instead of redoing the work to do it, if it knows that none of the inputs have changed, you can safely retrieve the output artifact from this cache. And this is a huge opportunity for optimization at your organization because you're not bound to keep this cache local. You can share this crop-- this cache across your entire organization, and all of your developers can populate this cache, and not only your developers, but your CI system can also populate this cache. And then whenever your developers are doing builds, Bazel can then check the cache and see if the artifacts that it needs are already present. And if yes, simply retrieve them without doing any work at all. So this is some example of how this cache might be shared. And of course what this means is that, for example, the first built of the day will also be fast. If you say have your cache, and it's-- sorry. If you have your CI system populating this cache, then when your developers get to work in the morning, they do their first build. That build will probably be trivially fast because almost all artifacts will be cached, very similar to the example above before I change the test. All right. And this cache can be anywhere. So you can use Google Hub-- Google Cloud Storage in order to have this cache be in the cloud not hosted by you. But you can also set up this cache to be hosted on premises for everyone to use. And the final property of Bazel that we're going to go over is that it's fully cloud ready. And so because of all the previous properties that we talked about, its hermeticity on its determinism, not only can you store each of the intermediary artifacts, but you can also do the work on the cloud. All of the build actions can happen in the cloud. So we're going to look at an example of another build. So in this example, in this example, as before, we're imagining we're starting from a clean slate. Everything has been cached. But this time, instead of changing a test file, this is editing a source file that is at the very bottom of the project. Nearly everything in this project depends on this source file. And so, now you're going to expect a full cache miss. You're making a unique change to your project. And so there's no way that any artifacts will be in the cache. And so Bazel will do its incremental build, but the incremental build still is a lot of work. And so it's going to start working, but now you're bound by the local compute power that you have. So we're actually going to let this keep running in the meantime. But as we said, these builds can be moved to the cloud so that you're no longer going to be bound by the compute resources that you have. So, to demonstrate that, we have this project. And similarly as before, we're going to start from a clean fully-cached slate, and then we're going to make the same edit to the same files that we did before. And again, this is a file that everything depends on, so Bazel will have to do all of the work to rebuild all of the project and rerun all of the tests. But then when we invoke Bazel in a moment, we're going to see that we're going to pass an additional flag that tells Bazel to execute all of the build actions remotely. So this is a setup that has been done on this project. There's a bit of configuration. And then you pass this additional-- that doesn't work. Another dash dash config equals remote flag, and then Bazel knows to run these actions remotely. And if we see here, we can see that 150 actions are running simultaneously. So this project was configured with 150 remote workers, and Bazel is utilizing all of it. And this means it's running as many tests as the configuration allows for. So now what happens is now that we see that the number of actions running simultaneously is dropping, that's simply because there aren't any more tests left to run. And so at this point, you're simply bounded by your slowest running test. So let's just go back at this point, 142 tests have been executed so far. We go back to the job that was running locally. We see that only 20 tests have been executed in the time that we've been working. A couple of these tests take a while to run, so we will move on. But we see 154 have finished so far, and they're all running simultaneously. So 14 are still running. All right, so that was a demonstration of how Bazel will run in the cloud. And now I'm going to pass it on to Alex to talk about Angular and how they've been using it. ALEX EAGLE: Thanks, Danna. [APPLAUSE] Hi, everybody. My name is Alex Eagle. I work on the Angular team at Google. I'm the lead for our tooling team, which includes things like making the tools that our Angular users, about 1 and 1/2 million of them, use to develop their applications, as well as supporting our own team and our internal development velocity. And I want to tell you about how much Bazel has improved our lives. If you haven't heard of Angular. It's a enterprise-scale web framework for a building very modern web applications. And it is a big project. So how big is it? So as Danna pointed out, the development velocity on your project, it depends on how many people and how big the tests are. And you might think that you might-- we need to break up your projects so you don't run all the tests all the time. That's really not what we wanted to do. So we wanted to use Bazel so that we could run all of our tests all the time and keep our development velocity high. And our numbers, I just grabbed these off of GitHub, and in the last 30 days, we've had 92 authors, over 400 commits touching over 1,000 files. So this is, I would say, a pretty medium scale. I know a lot of enterprises have much bigger apps than this, but it is enough of a scale that we saw the problem the Bazel solves. So this is what our continuous integration time looks like. You can imagine a developer on the Angular team, one of those 95 people, having to wait an hour for all of the tests to run, and then they find out something was broken. And so you can imagine going through this round trip many times. This significantly hurt our development velocity. And I want to point out here that the numbers I'm showing here are non incremental, so this is just like the uncached build. That's sort of the detail of the fact that we get contributions from the open source community, and so using a [INAUDIBLE] cache has some security risks for us. And so this graph is showing that 60 minutes is before we enabled the remote build execution, the dash dash config equals remote that Danna showed. And today, I just checked this morning, and a typical round trip time is 7 and 1/2 minutes to run all of the tests. So this is a decrease of 87% on our test time, and it has made a really big difference to the Angular team. There are other features of Bazel that have helped us out a lot. This is easily worth the investment that we put into migrating our build to Bazel. So this talk is about developing like Google, and the Angular project itself is just a small part of all of the Angular work that goes on at Google. We have a lot of customers internally, over 600 of them, and some of these applications you've probably used. And all of these applications rely heavily on remote build execution to allow a very large number of Google Developers to be productive working in these applications. And yes, we write full stack integration tests and expect them to run all the time. So now that Angular itself has been successfully ported to Bazel, we want to make it possible for all of you, if you're using Angular 2.0, to the same thing. And so as-- we're developing an opt-in preview which will ship in the next month as part of version 8 of Angular, that will allow all of our enterprise users to be able to opt-in to using Bazel. We will plan to work with them over the next six months to help them find patterns of porting parts of their builds to run under Bazel and allow them to use remote build execution. And I also want to point out that our plan for version 8 is that, if you don't have a very large scale project, there's actually no porting required. Bazel can just drop into your project. It's really for the enterprise use cases that some extra migration work will be needed. So there's one more thing I want to talk about. We showed how build and test can benefit a lot from incrementality and can be run by Bazel, but we're at the cloud conference, and we are all thinking about deploying services. So let's talk about deployment for a minute. A year and a half ago, when the Angular team switched to Bazel, we also switched how we do our own deployments. And so, we run basically a loop over our packages of just doing Bazel deploy of each one. That's not that interesting because we're a library. And so our deployment is a shipping an artifact to a registry. What's more interesting is that we have an example application that looks like an enterprise Angular app would, and as Danna showed, only the change packages get rebuilt when we do a deploy. So Bazel's smart enough to know what work it needs to do. But then, the changes that are produced by that can go into a new layer in the docker image. And then only that new layer needs to be uploaded to the Container Registry because, of course, Docker has the property that each layer has a checksum, and if the checksums match, it doesn't need to do any work. So the incrementality benefits can go all the way from your build through to your deployment. And so I have a quick video showing that. So this is our example application. And you see there's some text there. The live edit and deploy. And so we're going to make a change to that text. I should point out while this is running that all the demos you've seen today were actually Angular itself. And so those 174 tests Danna was running was the Angular repository. That was a demo of our actual day-to-day development experience. So now we're going to run deploy dot replace. So the deploy target is a Kubernetes target. This is going to go to Kubernetes Engine, and the replace is just a verb saying what we want to do. If we were making a new application we would say create. And so Bazel, as you can see, 13,000 actions didn't need to be run. So we got a lot of cache benefits now. And then the remaining part, the work that's still happening here, is we're bundling up the application. We're running some slow steps to do the production optimizations for this application, and it is a medium scale app. So that takes some time. And then once the app is fully built, Bazel knows how to construct the Docker image for it. And so now we see this image layer is running. It's running too quickly for me to talk over, which is good. And then the gzip happened, and so now there's a kubectl command running. This is the command line utility that deploys to Kubernetes. So again, I did all of this with one command, and I didn't need to say what needed to be built first. I just said, just like redeploy me. I don't know what changed. So now we're going to wait for Kubernetes Engine to spin up some new workers with the new code. There's a load balancer in front, and so now that LiveEdit shows up in the application. So that's all we have. We're happy to answer some questions after the talk. We'll be over here in this area. Thank you very much. [APPLAUSE] [MUSIC PLAYING]
Info
Channel: Google Cloud Tech
Views: 4,207
Rating: 4.757576 out of 5
Keywords: type: Conference Talk (Full production);, pr_pr: Google Cloud Next, purpose: Educate
Id: lDyIc2Abkwg
Channel Id: undefined
Length: 17min 57sec (1077 seconds)
Published: Fri Apr 12 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.