On March 25, 2019, gophers (Go developers) from around the world, and especially Europe, once more gathered for the dotGo conference at the Théâtre de Paris in the city’s 9th arrondissement. Organized almost annually by the dotConferences team since 2014, this one-day TED Talk-style event focuses on the Go language, its ecosystem, and the challenges that come with it. Here’s our summary of this year’s presenters and their talks.
Optimizing Go Code without a Blindfold by Daniel Martí
It’s tricky to get coherent, stable benchmarking results on non-dedicated hardware. Daniel Martí, a Senior Systems Engineer at an online banking and payment infrastructure company and a Go contributor, gave us some tips on how to reduce volatility while achieving greater stability. Having consistent results helps us decide if a new implementation is valuable or not in terms of performance.
Martí talked about perflock, which stops laptop systems from throttling and has a big impact on performance and consistency, as it allows your computer to reach maximum speed without reducing performance to avoid overheating. He also discussed the wisdom in not looking for a specific result, because it might not be relevant in the whole result set and, given enough time, you’ll find what you’re looking for.
Achieving Maintainability with Hexagonal Architecture by Kat Zień
Ports and Adapters Architecture (aka Hexagonal Architecture) is a term that was coined by Alistair Cockburn on his blog in 2005, but in reality, it has been around for much longer, applied under different names and by different people. At a certain scale, this way of structuring a project helps to break dependencies between packages and keep the business logic clean of low-level implementation details or user interface (UI) logic.
The Hexagon monniker refers to the technique of drafting architecture in concentric hexagons. In the center is the domain, which contains the business logic, from which arises the app hexagon that contains the glue that will connect the domain with the last hexagon, thus forming the framework.
Once each component is cleanly separated, it becomes easier to test and easier to know which of the below tests should be run on each component:
- Unit test for the domain layer
- End-to-end test for the application layer
- UI test for the framework layer
This is possible because each external layer will implement an interface defined in the contained layer. Therefore, the trick is to abstract the implementation and always go inwards.
In her presentation, Kat Zień, a back-end developer in the fincrime team at the mobile-only bank Monzo, explained how this method of structuring enhances the maintainability of a project in the long term. This is thanks to its method of decoupling components from each other and linking them only through very well-specified interfaces that are testable.
Go as a Scripting Language In Linux by Ignat Korchagin
Some people wish Go was more than it is and would like to use it in another way. Ignat Korchagin, a Systems Engineer at Cloudflare, wishes Go were a scripting language. Despite all the benefits of it being a static, typed, compiled language, he feels that being able to run some Go code by inputting something as simple as ./script.go would be nice, and in his talk he ran us through his attempts to make it work.
First, he tried to use a shebang to automatically run the script with go run. It ran, but the Go compiler didn’t like the unexpected ‘#’. Other developers have also tried to get the Go team to come up with a way to comment that doesn’t involve using // or /* */ , to no avail.
Learning how the shebang worked under the hood, Korchagin discovered he had to go deeper into the mechanism and so tried using the binfmt_script Linux mechanism. That had some success, but eventually he ended up using binfmt_misc to achieve the exact behavior he wanted.
Better x86 Assembly Generation With Go by Michael McLoughlin
In this talk, Michael McLoughlin, a Senior Software Engineer at Uber Advanced Technologies Group, exposed the dark secrets of assembly connected to Go. The language itself contains some parts of assembly in performance-critical sections of packages (most notably, crypto and runtime).
Assembly is quite simple in essence, but also very complex. Its biggest downfall is maintainability: It’s hard to read, hard to understand, and hard to fix. That’s why McLoughlin decided to create avo, a toolkit for writing assembly in Go that will generate the exact assembly you wrote, plus help from high-level functionalities such as virtual register or basic Go language features, such as loops and checks. It can also help to reduce the quantity of pure assembly code that the Go team has to maintain and improves the assembly’s quality at the same time.
Constant Time by Dave Cheney
Dave Cheney, a member of the technical staff at VMware and a well-known gopher in the community, has always held a critical view of the Go language and, in his talk, he focused on sentinel errors.
The way the Go library is set up, they are used in a way that means they can be abused or tricked into making a program that has multiple bugs or is not secure. He proposed that if we have to use sentinel errors, we should define them as constants so that we can communicate about how to implement them and not use them in the application programming interface (API).
Multi-Module Repositories by Jean de Klerk
Google created Go for scalability reasons: Scalability of programs, but also scalability of teams. The new way to deal with dependency has been set with Go modules, and for big teams, having multiple modules under one big repository can get tricky.
To deal with this kind of situation, Jean de Klerk, a Google Engineer working on Go libraries, showed us how to promote sub-packages into their own module and manage versions of interdependencies in the same repository.
Get Going with WebAssembly by Johan Brandhorst
Since the release of Go 1.11, WebAssembly (Wasm) has been a target for compilation. It is a good alternative to GopherJS and might be the future for more than the web (just look where it’s going with WASI).
Using the full capacity of Go, Johan Brandhorst—a Software Engineer at the data collaboration technology provider InfoSum, as well as a big advocate of gRPC and a freaking open-source contributor—live-demoed an app using the full gRPC-web package compiled as Wasm (and weighing more than 15MB). However, with TinyGo, an alternative compiler aimed at microcontrollers, these large Wasm binaries can shrink by 2 orders of magnitude.
The future of Wasm is bright, as being able to code a web application front end with the speed and power of Go is very attractive, and since its reach outside of the browser can increase, it will present attractive opportunities to do more.
Go Tune Your Memory by Bryan Boreham
Go is not Java. True, they both have garbage collection, but clearly Go doesn’t have the same range of options to tune your garbage collector (GC) as Java. Indeed, Go has only one option: An environment variable called GOGC, with which it’s still possible to tune the GC to adapt well to loads.
Bryan Boreham, Director of Engineering at Weaveworks, ran us through how to do it to improve memory consumption and CPU usage. The GOGC should have a numeric value, which is the percentage the runtime will allow the garbage to grow before collecting it and is based on the minimum heap size after a garbage collection. If you set the GOGC to 50, it will collect garbage if the heap grows 50% larger than the minimal heap size of your program. It will then collect more often. Therefore, this means you’re trading CPU power for memory consumption. However, if memory is not a problem and you need to keep all your CPU cycles for working, you can set the GOGC to more than 100, so that the garbage collector does its work less often until it hits your set value. And you can even forget everything we said and turn the garbage collector off, using GOGC=off. With this you can run short-running programs with low memory usage way faster, but they might crash.
As with everything in computer engineering, it’s all about trade-offs, and you should use what you need for the job.
Go for Phallic Object Generation by Ellen Körbes
This talk contained the most unexpected narrative for a tech event, yet it got a great reception (proving that the Go community is pretty inclusive in general). Also, it was presented with lots of humor while still highlighting the problems trans people have to live with as “outsiders.” Its conclusion was epic, and if you’re thinking about replaying a talk, this is a great one to watch!
Shattered Mirror: An Introduction to Reflect and Unsafe by James Bowes
Facing some complexity when implementing a state machine at work, James Bowes, Chief Technology Officer at the independent developer services marketplace Manifold, and his team decided to use the reflect package for dependency injection at runtime.
Using his experience as an example, Bowes ran us through the advantages and shortcomings of this decision and explained how the unsafe package works in the background. As
reflect is a high-level package, it is connected to very low-level details and the
unsafe package, which permits dealing with unsafe pointers. Reflect proved to be powerful and versatile, but very hard to debug, as Bowes and his team didn’t know what they were dealing with, which made the stack trace more complicated to understand.
In conclusion, Bowes shared that
reflect is a good tool for reading and writing some data in arbitrary types, but the calling function was too much of a hassle to maintain in the long run. As for
unsafe, it’s better to stay away from it, since it kills the point of a type system.
A Dive into RISC-V by Jessica Frazelle
Nowadays, modern server computing is mostly done using X86-64 architecture, and a few cloud companies are having some success with Arm servers. However, RISC (reduced instruction set computer) is coming back with version V.
Jessica Frazelle, aka the Queen of Containers, taught us about the different types of computer architecture, including the one instruction set computer! She discussed the advantages of RISC-V architecture: It is completely open source and free of royalties, which have hindered innovation in this area in the past. It also helps kernel development, because there is no need to ask yourself if the bug comes from you or your chipset’s firmware... or if anything goes directly to the NSA with a special instruction!
Of course, Frazelle wants Go to run on this architecture, and gophers such as Tobias Klauser are trying to make it reality.
Go 2 Error Values Today by Marcel van Lohuizen
After tackling Go 2’s errors language feature, Marcel van Lohuizen, a Go team member at Google, started working on a few additions to the errors package itself.
Despite its efficiency, Go is not known for having the most elegant error handling. The developer experience can still be improved by removing some of the burden in classic error management patterns. Inspired by some ideas coming from the Upspin project and other different community packages available, van Lohuizen proposed testing those additions in 1.13 and made them available in Go tip. So far, it has won support among Go team developers, thanks to the simplification it led to in the Go source base.
Though error language specification is happening slowly, it seems like this update for the errors package is getting adopted ahead of the curve.
Dockerization of Go by Joan López de la Franca
Joan López de la Franca, a Software Engineer at Atrápalo Engineering, quickly delved into the concept of Docker, explaining the concept of images, containers, and layers.
Since Go is a static language, not many external dependencies are needed. We can just use an image reduced to its minimal set of dependencies and your Go binary. With the multi-stage Dockerfile, this is now easy to achieve, as you don’t need a full continuous integration to separate the build part, which needs the source, from the image-creation part, which only contains the Go binary with the most minimalistic sets of dependencies (/etc/passwd, /tmp, ca-certificates, tzdata). De la Franca advised us to use the distroless images made available by Google.
ONNX-Go: Neural Networks Made Easy by Olivier Wulveryck
Olivier Wulveryck, a Site Reliability Engineer at OCTO Technology who is also making himself known in the wonderful world of AI, introduced us to the concept of the deep learning model exchange format known as ONNX. He created a proof of concept that imports an ONNX model into the gorgonia runtime. With that pretrained model, he was able to convert handwriting into numbers.
This is a big step in making Go a valid language for machine learning so that it becomes a top machine learning language like Python, R, and C++.
TensorFlow and Go by Natalie Pistunovich
TensorFlow is a well-known framework to use when doing deep learning work. For a while it was only accessible via C++ and had bindings for Python and Java. The API for Go has previously been much more limited, but in the past few years it has been improved to the point where it can be relevant in a lot more use cases.
Natalie Pistunovich, an Engineering Manager at Fraugster and the founder of GopherCon Europe and Women TechMakers Berlin, showed us how to load a pretrained model in TensorFlow using Go that would be able to predict and read letters from a CAPTCHA image in a very simple and fast way. She encouraged us to do the same and hack with it!
The Monsters inside the sync.Locker by Roberto Clapis
The sync.Mutex, a simple abstraction from the Go library, is behind the functioning of channels. Roberto Clapis, a Security Engineer at Google, briefly explained how mutexes work and how they use the atomic package behind the scenes. As close to the metal and as optimized as the atomic package is in letting you code, it can trick you in many ways by starving your goroutines. The best approach is to avoid using atomic and stick to using mutexes and channels, because they already do a lot of work.
Semaphores by Valentin Deleplace
Concurrency can be hard, but Go helps us a lot with channels and mutexes. Valentin Deleplace, a Software Engineer at Google, used the analogy of a swimming pool to run us through what to do when problems arise when too many people want to “get in” at the same time.
He modeled semaphores as a limited number of bathing caps, which are required to access the pool, or as a fixed amount of lockers available for you to put your gym bag in. Using GopherJS, he demoed his code, rendering the swimming-pool simulation in his browser.
What we learnt from the event
- The Go language is still thriving, as proved by 2018’s survey from the Go Team and dotGo 2019.
- As stable it is with the Go 1 compatibility promise, it has been applied to a larger amount of use cases, from low-level ones with TinyGo to 3D modeling, AI, and Wasm. There are many applications and plenty of room for it to grow.
What we liked about the event
- Having missed only one dotGo since its inception, we feel it’s improving every year. The dotConferences team has clearly listened to attendees’ previous suggestions and acted upon them, which made the event run more smoothly.
- As always, the Go community is nice and welcoming, making the event even more enjoyable. The pace is also well balanced, meaning you are able to digest a lot of information from the talks, but are still able to chill and chat with other groups of people in the hall.
This article is part of Behind the Code, the media for developers, by developers. Discover more articles and videos by visiting Behind the Code!
Want to contribute? Get published!
Follow us on Twitter to stay tuned!
Illustrations by WTTJ