 All right, so I think we can slowly start. So I didn't expect so many of you, so really, in the morning. So I hope you grabbed your morning coffee and we can start. So the session today will be about Go language. I'll try to present our experience using Go and compare it and contrast it a little bit with C. And before I start, how many of you have been using Go before? OK, how many in production? All right, not a lot. So I hope after this talk, we'll have a bit better overview of what Go is and what its limitations are and what are the advantages as well. So let me start with my personal view on Go. It's very subjective opinion, but also supported by my colleagues who are also using Go. I really think it's a very productive programming language, especially when it comes to some kind of network programming. And I'm not necessarily mean it's any kind of like heavy server programming, but rather any kind of application where you are using network for communicating. And I am by any means not claiming that Go is a replacement for C because there are many places you cannot replace C. And it's not Go. It's any language in general, like when you are doing some kind of like hard real time systems, operating systems, device drivers, all those places are irreplaceable by any other language, I think. And during this talk, I will start with telling you a bit about Go itself and our experience with selecting Go as a programming language. Then we'll look at basics and some code samples. And finally, I'll present to you some demo application. I'm having Bigelborn with a simple Go application running a couple of sensors here. So I will try to show that. And a little bit about me. So my name is Marcin Pasinski. I've been doing software development for more than 10 years. It was mostly C and C++. But recently I'm doing also Go development. There are my contact details there if you want to reach me out after the presentation. And at the moment, I'm working for Norton.tech. And the two very relevant for the stock products we are developing are Mender, which is over-the-air updater for embedded Linux devices. It's integrated with Yocto. I don't know how many of you have heard about Yocto before. So it's fully integrated with Yocto. It's written in Go. And we are having booth at this conference. And later today, we will have a booth as well. If you are interested, then feel free to join. And the other product we are developing is CFEngine. Someone heard about CFEngine before? OK, a couple of people. So this is written in C. It's actually right now. It's like 20th anniversary of the product. So it's there for a long time. And I've been involved in developing both. So I feel I have quite a nice experience with developing both Go and C code. So a little bit on Go timelines. So it's a fairly new programming language. It was conceived in 2007 at Google and was announced in November 2009. And Go has been started by writing a language specification. So it was possible to start some independent work on writing front-end for GCC by Ian Taylor in 2008. And then the first official release was in 2012. And Go guys are trying to keep half-year release schedule. So five years later, we have Go 1.9 release August this year. And some of you might ask, why do we need yet another programming language? We have plenty already. So Go was created by Google to meet the needs of Google developers, basically. And it's supported by Google all the time. And I really do think that all the programming languages reflect somehow the physiotherapy of the creators. So Go was born to fix, somehow, improve the issue of the system suffering from an explosion of complexity at Google. So simplicity, together with efficient compilation, efficient execution, and easiness of programming were three main principles for creating Go. Now let's move on to why we've selected Go for developing our new product. So when we started discussing and decision-making process, we somehow divided the requirements into two groups. And in the first one, we've placed all the things which are somehow facing the end users. And the second one was more internal points. So I would expand a little bit on both. So at the point when we started developing our new product, we knew that our application will be running on embedded devices, and that we want to provide easy integration with Yocto. So in the first group, we've put size requirements on the device, so the smaller, the better. Then we knew the Yocto thing. And we knew that it will run on embedded devices, so possibility of cross-compiling for different architectures was a must. And then in the other group, we put more internal things, so competences in the company. Obviously, the more people know the technology, the better. Then we've been discussing possibility of sharing and reusing the existing code base we've been having. And then development speed. So I'm just wondering how many of you have faced pressure to add new features fast to ship the code quickly? It's great if you always have time to do the simple, nice code, but it's not always the case. So very often, you need to neglect simplicity. You need to do some kind of workarounds and stuff. So Go is really productive language, and this was a big point for us. And then we knew that our device will be so-called IoT device, so some kind of network connectivity will be needed. So we've been looking for access to network libraries, like HTTP, then SSL, JSON. And then we've been also discussing some kind of things that will make the programming easier and less error-prone, like automatic memory management, for example, or security enablers, think, like buffer overflow protection and stuff like that. So based on our findings, we've created a comparison of a couple of languages. And C, C++ and Go were three to somehow go to the final round. And you can see here how those compare to each other and how they fulfilled our requirements. And this is the state as when we discussed all the things. So right now, a couple of things changed, like competences in the company. So more people know Go right now. And then when we started with Go, we needed extra layer in Yocto. But right now, there is the small asterisk. As from Yocto Pyro release, Go is fully integrated with Yocto so you don't need any extra layers for developing Go code. And then we did some more tests using Yocto. So we've been checking image size, then image size with network stack, because we knew that we'll need some kind of network connectivity. And then we've been also discussing how we are delivering the end artifact to devices. So Yocto can be actually statically compiled to the single binary. So we don't need any virtual machines and any extra dependencies running on your device to use the Go code you've been developing. And after heated discussions, we finally decided that we'll go with Go. So the main reasons were that Go is having extremely rich standard library. So a lot of features there. And it allows fast development of applications. Then in turnout, that learning curve from C to Golang is not very steep. And in fact, from C, Go is inheriting a lot of things like expression syntax, control flow statements, data structures, pointers, passing by value, parameter parsing, so a lot of things. And also if you know Python, like string handling is kind of like Python is. And Go is also compile language. So Go is having optimized compiler and runs natively on embedded devices. Can be statically linked. I'll expand on this a little bit later. And then there is really nice coverage for cross compilation. And we've been also doing some tests with the size of Go application. And we've been trying to compare it with static C binaries. So as you will see, there are not such a big differences. And we've been also fairly important thing for us was that we could develop both backends and the client in the same language. So we've been discussing all the possibilities of sharing the code, sharing developers. And I'll expand a little bit on both size and performance of Go application. So the first example here is the smallest Go application you can write. It's Hello World. And it's using built-in print line function. And after stripping debugging symbols, it's 600 kilobytes a little bit more. So this is basically what the Go runtime overhead is. But if you are trying to write through Hello World application, what you will do is you'll include a font package. So then the binary is much bigger. But a font package is having a lot of dependencies. So 10-ish packages are included when you're compiling the code with font package included. And to compare with C, if you are building dynamically linked library, then it's really tiny, like eight kilobytes. But obviously it has a lot of dependencies. And if you do the same static abstract from the fact if it's a good idea or not, then it's bigger. So after stripping debugging symbols, it's 800 kilobytes. So even bigger than Go binary. And then a little bit on Go speed. So initially the title of this site was performance. But I'm going to talk about the speed in general. So if you're interested in performance, then maybe you're familiar with this computer language benchmarks game. So you can follow the link and see the detailed benchmarks of various programming languages. So you can see how Go compares to other languages, how it's doing with executing various algorithms. But in general, Go is fully garbage collected. So this slows down the things. And there are ways to switch the garbage collection off. But I'm not experimenting with this stuff. And I'm not sure if it's a good idea. Then you cannot really say where the variable will be allocated. So we've seen you can decide that you want to allocate the variables on the stack or on the heap. With Go compiler is trying to make some educated decision where the variable should be. You can see where the variable will be allocated if you pass correct build flags. But you cannot force compiler to use the stack only, for example. But on the pros, Go is providing really extremely fast compilation. So our source code, for example, is 15,000 lines of code. It's the client only. And the compilation takes 1.4 seconds. And if you're doing some kind of concurrent programming, then Go is really well designed for doing this. It's very easy, and it's very performable. And then the thing we've been discussing already, like the speed of developer. So I really do think that Go is a productive language, and you can develop your applications fast. So turning your attention on Go itself, we'll talk about a couple of things why I like Go. So among the others, the standard library. So Go is, the standard library is having more than 100 packages. And just naming a few, like runtime, you can set some runtime things like garbage collection. You can switch it off. You can select how many threads you want to use. Then flag for building command line interfaces, for parsing command line arguments, net for any network communication. Then various data types with an encoding package, really rich crypto package. So a lot of things you can do there. Then unsafe and syscall at the end, very useful if you are doing any kind of embedded-ish development. Then Go comes with a lot of building tools, like thumbed for formatting the code. So Go forces you to use some and only one correct coding standard. Then there is test package with test coverage, some profiling tool, Godoc, for creating documentation from inline code commands. So it's kind of similar like Doxygen. Then GoVet for doing static code analysis, race detector. And really, many more, there's a lot of tools coming with Go by default. And then a little bit on compilation itself. So there are two Go compilers you can use. The original one is called GC. And it's written and maintained by Google. It's part of default Go installation. But there is also GCC Go, which is front end for GCC. And this one works fairly nice, but it's lagging a little bit behind GC. So right now, GCC 7 supports Go 1.8.1. But I think GCC 8 will support Go 1.10. So it's not very far behind GC. And as I mentioned already, compilation is extremely fast. And this was one of the principles of creating Go. Then you can create single binary file, no extra dependencies, no virtual machines. But we'll talk about this a little bit later as well. And you can still use make files if you want. So the link shows an example of our make file we are using. And cross compilation. So a lot of platforms supported. So to cross compile a Go application, you need to set two flags, Go-S, which is operating system, and Go-ARC. And then just type Go-Build. And it will cross compile binary for a given OS and a given architecture. So quite a wide selection of both OSes and platforms supported. And then a little bit on debugging. So you can still use GDB if you want. But there are some core network cases where GDB don't work extremely nice with Go, particularly heavy concurrent applications. GDB is having some issues when trying to debug those. But there is dedicated Go compiler called Delve, very similar to GDB, almost the same user interface. Then testing. It's extremely easy to add unit tests and benchmarks to Go code. So testing is built in the language. And all you need is to create a file with a test suffix and then add a test prefix to your function, import testing package. And then the only thing you need to do is run Go test. And all your tests will be automatically picked up from your source and executed. So right now, I will go very quickly through some code samples. So you can find it in many places. But just to give you some overview of how Go syntax looks like. So here we can see how to declare variables. And the variables are pretty much the same as in C, the basic ones. So what's different is at the end, you have this F colon equals 1. So this is like shortened syntax for declaring variables. And then you can do like tuple assignments. So multiple variables having multiple values functions. I guess what I want to emphasize here is that you can have multiple return values, which is very useful. So you can return the value and error, for example. We are using this a lot. Then Go is not object-oriented language, or at least this is something that Google guys are claiming. But there are some object-oriented principles in the language. So you can create a struct. And then you can create a method on the struct. So the funk s square area. So square is a receiver. So it's kind of like this pointer in C++. So you can call this function on the square object. And interfaces are also some kind of object-oriented principle. So those are not defined explicitly, like in Java, for example. Like this object implements this interface. So in Go, if the type has given a function, it satisfies the interface implicitly. And then you can have like, if you see the main snippet, you can call the function on behalf of the interface. So you don't necessarily know in the runtime what kind of object or what kind of type this is. But as long as it implements the print function, then it satisfies the print interface, and you can use it dynamically. And then a little bit on concurrency. So Go is having two built-in mechanisms, GoRoutines and channels. So GoRoutines are kind of like lightweight threads. But the initial size is only two kilobytes. And Go is having its own internal scheduler. So the GoRoutines are multiplexed like M2N to OS threads. And then there are channels. So those are like pipes for exchanging messages between various GoRoutines. And you can have blocked and non-blocking channels, buffered, unbuffered, very useful way of exchanging messages. And those are used a lot for synchronizing the threads, the GoRoutines as well. And it's very easy to create a GoRoutine. The only thing you need to do is to add the Go in front of the function. And when you do this, the function is executed concurrently. And the channel is also very easy to create its make, and the type of the channel. And then there are two operators to write to the channel. It's this R2, the channel, and then to read from the channel. So you can also use your C code with Go. So there are some bindings for C applications. So the only thing you need to do is import C. And then Go is creating this virtual C package. So when you are using any package in Go, the syntax is like package name, dot, and the method or the type from the package. So it's the same with C. So if you're using a C package, then you're calling C.something to some C function. And a quite important note here is that Go is garbage collected, but C is not. So if you're using any C variables in a Go code, which are allocated on the heap inside C code, you need to explicitly free those variables inside Go. And then you can also use C++ inside Go code. I haven't been using this myself, but there is this simplified wrapper and interface generator. So this was created to kind of bind C and C++ with languages like Python, for example, interpret languages. So there is also Go module to C++. So you can use C++ inside Go code. And then I said that Go is compiled to the single binary, but you can also use the shared libraries. So it's working on x86 architecture only at the moment, but you can both create like Go shared library that will be used inside C code. And you can create like Go shared library that you can use inside other Go applications. So very useful when, for example, you want to replace only a part of your C application. So you can easily create shared Go library. And then you can use this library, include this library and link against your C application. And a little bit on embedded Go. So as I said before, you cannot really force Go to like use stack only or you cannot say where the variable will be allocated. But you can see if you provide this minus gcflags, minus m arguments, where the variable will be allocated. So Go is based on the size of the object. And Go is doing something called escape analysis to see it tries to avoid dangling pointers. So you can have a local variable inside a function, but you can return this variable. So in C, you'll have a dangling pointer. With Go, Go is trying to be smart enough to allocate this variable on the heap. And then inside other functions, you can still reference that variable. And then unsafe code. So if you want to write something directly to memory in C, you can, whether you like this syntax or not, you can use it. But in Go, it's also possible to manipulate hardware directly, but it's intentionally hard. So here is the sample of manipulating GPIO Raspberry Pi and its memory mapped GPIO. So as you can see, you can like syscall map and then map the file. And then you're using a lot of unsafe pointer things to address memory directly. So it's there. It's possible. It's also not pretty, but you can use it. And I would like to talk a bit about our experience with Go so far. So there is a lot of positive things about Go we like, but there are also things I personally think could be done better. So when you are using third-party libraries, there is no standardized tool for this. So there is plenty of third-party tools for rendering external dependencies. A little bit messy, could be improved, but I think Go guys are working on this actively to create some built-in tools for fixing this issue. Then there is quite a lot of external libraries out there, but there is a lot of really bad ones. So you need to be very careful what kind of libraries you're using. And then when we started with Go and the Okto, we've been having some issue with building Okto images because Okto was not supporting Go natively, so we had to use some third-party layers to build Go code. We've been fixing those layers a lot because not everything was working out in the box for us. And then before Go 1.5, there's been also issue with bootstrapping the Go code, so it wasn't extremely walking the park to build the Go binary. But right now, Go layer is integrated with Okto, so all the issues we've been facing at the very beginning two years ago are gone right now. And I've been also mentioning about extremely nice compiling and cross compiling. So this is gone when you're using CGo. So when you have some C bindings inside your Go code, then it's not as easy as when building Go-only applications. So when you have C bindings, then you need to provide all like C infrastructure, cross compiler and stuff for building C part of Go application. But at the same time, there is a lot of things that we like in Go. So it was very easy to do the transition from C and Python, so it literally took a couple of days to be fairly productive with Go. And then we are using Go tools and standard library a lot, and those are really nice tools. So we are not in fact using a lot of external tools for doing the stuff we need. And we've been also discussing at the beginning before we started developing our product in Go that we'll be able to exchange some kind of tasks between backend team and the client team. This hasn't happened a lot, but we have some shared libraries. We are using our shared code bases and we've been able to use a lot of infrastructure. So for example, CI looks more or less the same for the backend and for the client with some small differences. And I really do think that Go is very productive language. So if you need to develop your application fast and if you need to include some kind of network communication, then it's very productive. And this is kind of like mixed feeling, the last point. So a lot of people disagree with this and a lot of people don't like this. But I really think that first coding standard is a really nice idea because no matter what kind of code you are looking at, it's always the same. It looks the same. And also you don't have to spend like hours before you start developing. Should we use this coding standard or something else? It's there, it's only one way of developing applications in Go and it's forced. So it's very easy to read the code. And right now we have still like 10 minutes. So I'll try to show you a demo of embedded Go application. So I'm having here a Bigelbon with probably it's hard to see at the back but I'm having DHT11 like temperature and humidity sensor. And then I'm having infrared distance sensor here and a small buzzer as well. It was disconnected from the power but maybe I'll connect it now. And I'm running here a like application that exports all the readings through web interface. So we can see how this works. You can take a look at the code. So this is how I'm compiling my application. So if you're familiar with Yocto, it's very standard. We don't need any extra Go layers right now any extra commands. It's like BitBake and I'm building an image for my application. It's taking a while. So maybe while it's building I will show you a little bit of source code. So this is main Go file. So it's like first file that it's compiled or inside this file. Go is looking for the main function. So this is where everything starts. So here I'm initializing some in-memory store for like storing a couple of last readings. And then we are creating a channel for reading data from humidity and temperature sensor. And then this, you can see Go here. So this is co-routine. So functions run concurrently. And this function is waiting, blocked waiting for the data from this DHT11 sensor and then stores the data inside the memory. And then this go read the DHT function defined later is actually calling read the humid temp. So this HIO model is the one created with C Go. So I'm having couple of C and H files. And here DHT Go, so I'm importing C. And for reading the data from the DHT11 sensor, I'm simply calling this C function. And then I'm converting the return values to Go ones. And I'm returning this from the function. So quite easy to do this stuff. And where's my mouse? Here we can see also how easy it is to start a web server. So the start server, you are creating a handlers. So what kind of functions will be executed when different regx will be matched. And then the only thing you need to do is listen and serve and provide the port on which you're listening. So my application is built. So now I can update my device to start this application. So to do this, I will use Mender. So I can see I have couple of devices here. So I'm accepting my device. And once it will be authorized, I'll be able to create a update for this device. So this is my Bigelbon and it's running release two at the moment. And first I need to upload artifact. So it will be this one. Okay, then devices again. And I want to create a deployment for this device. Okay, now deployment is pending. So device will first try to connect with the server and the feature out that okay, there is deployment for this device. And right now it's downloading the image. So it's probably should take like less than a second. I'm on a local network. I could do SSH as well to copy the binary. But in this particular case, the device is here. So I can do like even SD image DD and then copy to the SD card. But usually in our CI, for example, the devices are out there somewhere. So this is the way we are updating the devices to test the applications and our application as well. So the whole image is pretty big. Probably that's why it's taking some time to download it. But once device will be, once it will download the image, it will reboot the device because it's like copied to inactive partition. Device is having two partitions active and inactive. And then this is for doing some kind of like failover if something goes bad. Okay, let's hope it will finish in a reasonable time. Okay, you can see this sound. So device is running with the new image. Maybe I'll disconnect this for a second. So device is rebooting right now. And once device is rebooted, we'll see that the new applications is new application is installed on device. And I will show you what this application is doing. So let's give it like a little more seconds. Okay, success. So device is updated. And right now I can... Okay, so right now we can see the latest reading from the DHT11 sensor. So the temperature here is like 22.8 Celsius degree. Sounds about right. And the humidity is 59%. We can also see like history. So this is some graphs, how temperature and the humidity was changing over time. We can do the data export, for example. And this is to show how easy it is. This was like literally three lines to convert the binary data to JSON and export it. So those are the last 10 readings of temperature. So JSON data, you can use it in like whatever you want. And then I have an inference distance sensor. So hopefully if something will be in range of the sensors, a sensor you'll see the red circle. And if it's out of range, then you'll see the green one. So let's try. Okay, it's kind of working. So I'm using WebSocket here. So when I am close to the sensor, then you can see, okay, it's there. And it's out of range. So this is basically it. So any questions, comments? Yeah, so the question was, if the history is kept on device? Yes, it's like right now I'm having probably like eight gigs as the memory card. So quite a lot of readings. But I've implemented like in-memory cyclic buffer for restoring 10 last measurements, but you can use some kind of like database for storing the data. So it's like actually your implementation. So the question was about crypto library in Go, if it's implemented by Go developers or if they're using some third party things. So I think it's a mix. So some of the things are like Go natively implemented, but there are some like bindings to other things. So question about licensing of Go code. It's some kind of like open source license, but I'm not sure about the others. I think it's GPL three, but I might be wrong. So we have a colleague of mine is like more into the license and he's dealing with all licensing stuff. So I'm sure it's sorted out somehow. But yeah, so it's BSD a license. So the question was that my demo is based on channels and if it's easy to use the channels to communicate with external applications. So not channels in particular, but you can use any kind of like inter-process communication. So you can use socket or you can use pipe thing, but channels are natively used by Go applications for communicating between different Go routines. So we cannot use the channels to communicate with other applications. So the question was, I mentioned initially that we've been having some issues with integrating our code with Yocto and what's my impression with the latest Yocto releases. So it's working extremely smoothly. We don't have any issues with like latest Go releases and like compiling Go code. Yeah, so the question was if it covers all the dependencies we are having in our application, yes. So we are using like besides of our extra layers for configuring the device, we don't need any extra layers for compiling both Go and the C bindings we're using inside Go code. Okay, any other questions? Okay, thank you very much and good luck with Go.