500 million • The Applied Go Weekly Newsletter 2024-07-07
Your weekly source of Go news, tips, and projects
Summer Break!
This is the first issue during the summer break. It's much smaller than usual, but I still managed to include some articles from this week. Only featured articles! Next week's issue (on Sun July 14th) will be a 100% "canned" one as I'll be AFK for most of the time. The week after that, the newsletter will slowly ramp up to normal size.
Enjoy!
Featured Articles
How I sent 500 million HTTP requests to 2.5 million hosts
Author: "I tried implementing it in Rust, but unfortunately, my brain is too small for async tokio types magic. Go, on the other hand, allowed the JS developer to write this whole thing, this is quite a statement about the language." – I cannot comment because I don't know Rust's Tokyo runtime. I took a quick, superficial glance at the docs and learned that Tokyo's mutexes are "non-blocking", which seems a contradiction in itself. Maybe Rust's std::sync
would have been an easier place to start with concurrency, but Go's concurrency model even more so.
How I sent 500 million HTTP requests to 2.5 million hosts
Resetting timers in Go
Beware of the dreaded timer leak! Anton Zhiyanov describes the pitfalls associated with time.After()
and time.AfterFunc()
, and explains how the Reset()
method fails to deliver and what to do instead.
GitHub - wroge/sqlt: Go Template SQL Builder and ORM
Templating is powerful and underused. Here is a proof of concept of a SQL query builder that uses Go's familiar text/template
syntax and semantics for constructing queries.
GitHub - wroge/sqlt: Go Template SQL Builder and ORM
Golang A to Z
A new Go resource page is in the making. Golang A to Z lists learning material, Go jobs, and more.
Generics: A Boon for Strongly Typed Languages
Some gophers frown upon the addition of generics to Go, worrying that the language became more complex. Nidhi Davra argues that generics are in fact an indispensable ingredient to strongly typed languages.
Generics: A Boon for Strongly Typed Languages
Go 1.22.5 is released
A new minor release is available. Release notes here.
Podcast corner
Cup o' Go | The Go release that was completely Expected, conferences, and cookies! 🍪🍪🍪
Expected... as in Expect: 100-continue
?
go podcast() 042: Gate keeping and teaching of programming with Ramesh Sringeri
Does IT lose talent due to gate keeping? Dominic St-Pierre talks with his guest Ramesh Sringeri about IT's homemade problems.
Go Time: Dependencies are dangerous
The polyfill.io attack seems to have spawned quite a few discussions about supply chain security (see also last week's issue). The Go Team panel discusses Go's dependency management and security thereof, in the light of the polyfill attack.
Go tip of the week: Concurrency and pointers
"Don't communicate by sharing memory, share memory by communicating."
This Go proverb describes a powerful concept: Communicating Sequential Processes (CSP).
Don't try sharing data between goroutines through a shared memory area that is guarded by an error-prone pile of intertwined mutexes. You quickly get into concurrent debugging hell.
Rather, have goroutines use their own local memory and exchange data by sending values around.
This works well... until you decide to create a channel of maps. Or a channel of slices. Suddenly, you get data races.
Why?
Maps and slices are data types that contain pointers under the hood. Those pointers refer to places in memory that hold the actual data.
And here is the gotcha:
Go strictly passes data by value. (Whether the data is passed to a function or through a channel.)
A pointer is just a value. In fact, a pointer is nothing but an unsigned integer that happens to represent the address of a memory cell.
So when Go sends a map or a slice through a channel, the internal pointer gets copied along. No deep cloning happens. (Because that's not part of the deal. Go has no reason to treat a pointer value as something special. Want a deep clone of a complex data structure? It's upon you to make that happen.)
Now two pointers exist in different goroutines that point to the same memory location. One in the sending goroutine, and another in the receiving goroutine. Congrats, now you have unprotected shared memory. The code is open for data races. The last update silently wins.
TL;DR:
Never send anything through a channel that contains a pointer. No maps, no slices, no structs with pointer fields.
Send primitive data types, strings (they are immutable), structs with plain value fields, or arrays.
P.S. Pro Tip: Whenever your code contains concurrency, Go's race detector is your friend.
Overheard on Mastodon
The year is 2030.
Computers boot directly into the browser. IDEs are just a web app now, running in the GPU. No one knows why. Or how.
All programs run in 4 nested containers on top of a hypervisor abstracting over the 5 major computational clouds. The last time a branch was predicted correctly, in any CPU anywhere, was 4 years ago.
Cloud costs are withdrawn directly from your retirement fund.
Ext7 just came out, it's written in Javascript and uses AI to guess what the file may contain.
– Chris Gioran 💔: "The year is 2030"
Completely unrelated to Go
Against Innovation Tokens
"Choose boring technology!" became a mantra after the article with this title gained popularity. The "Innovation Token" concept implies that new, innovative technology always has drawbacks like operational overhead, being hard to learn, etc. But sometimes, these are only stereotypes, not inherent properties. Instead of looking to minimize innovation, we should strive for maximizing consistency for our tool stack.
Happy coding! ʕ◔ϖ◔ʔ
Questions or feedback? Drop me a line. I'd love to hear from you.
Best from Munich, Christoph
Not a subscriber yet?
If you read this newsletter issue online, or if someone forwarded the newsletter to you, subscribe for regular updates to get every new issue earlier than the online version, and more reliable than an occasional forwarding.
Find the subscription form at the end of this page.
How I can help
If you're looking for more useful content around Go, here are some ways I can help you become a better Gopher (or a Gopher at all):
On AppliedGo.net, I blog about Go projects, algorithms and data structures in Go, and other fun stuff.
Or visit the AppliedGo.com blog and learn about language specifics, Go updates, and programming-related stuff.
My AppliedGo YouTube channel hosts quick tip and crash course videos that help you get more productive and creative with Go.
Enroll in my Go course for developers that stands out for its intense use of animated graphics for explaining abstract concepts in an intuitive way. Numerous short and concise lectures allow you to schedule your learning flow as you like.
Christoph Berger IT Products and Services
Dachauer Straße 29
Bergkirchen
Germany