I think I can confidently say that the following pattern is wrong in all cases. B ut it works… until it doesn’t.
Not convinced? Let's rewrite with
Even if this still doesn't convince you, this issue is documented in
https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/waitgroup
The problem is that
The runtime may schedule the goroutine later, so the counter might not be incremented yet.
Voila, now you've to debug why you missing data that was consumed but not processed!
And the fix is quite simple: any goroutine management should happen before the goroutine start:
{
...
for {
go process(...)
}
// some logic around atomicCounter waiting for a zero
}
func process(...) {
atomicCounter.Add(1)
defer atomicCounter.Add(-1)
}
Not convinced? Let's rewrite with
sync.WaitGroup:{
...
for {
go process(...)
}
// some logic around sync.WaitGroup.Wait()
}
func process(...) {
wg.Add(1)
defer wg.Done()
}
Even if this still doesn't convince you, this issue is documented in
go vet:https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/waitgroup
The problem is that
atomicCounter is updated inside a goroutine that happens instantly but there is no real guarantee that this will happen instantly.The runtime may schedule the goroutine later, so the counter might not be incremented yet.
Voila, now you've to debug why you missing data that was consumed but not processed!
And the fix is quite simple: any goroutine management should happen before the goroutine start:
{
...
for {
wg.Add(1)
go process(...)
}
// some logic around sync.WaitGroup.Wait()
}
func process(...) {
defer wg.Done()
}pkg.go.dev
waitgroup package - golang.org/x/tools/go/analysis/passes/waitgroup - Go Packages
Package waitgroup defines an Analyzer that detects simple misuses of sync.WaitGroup.
I made smth (tbh, I just open-sourced 1 internal pkg), 3 funcs but used dozens of times across the codebase.
https://github.com/cristalhq/ordx
Fuzz and race tests are always welcome.
https://github.com/cristalhq/ordx
cmp := ordx.RankCmp([]string{"low", "medium", "high"})
fmt.Println(cmp("low", "high"))
fmt.Println(cmp("high", "low"))
fmt.Println(cmp("medium", "medium"))
// Output:
// -1
// 1
// 0
Fuzz and race tests are always welcome.
GitHub
GitHub - cristalhq/ordx: Comparison helpers in Go
Comparison helpers in Go. Contribute to cristalhq/ordx development by creating an account on GitHub.
Any good
(links to blogs are also appreciated)
cloud-init configs for a small server for pet projects? Thanks in advance.(links to blogs are also appreciated)
oleg_log
I freaking love Google's open source. Just a pure engineering beauty, ass always. project $ scc . ─────────────────────── Language Code ─────────────────────── Go 46_539 Not great, not terrible. Go.mod/sum is also small as possible:…
Took more time to polish than I expected but at least binary went from 36Mb to 16Mb, yay.
https://github.com/cristalhq/fcm
(there are few things to add but nothing critical)
https://github.com/cristalhq/fcm
(there are few things to add but nothing critical)
GitHub
GitHub - cristalhq/fcm: Firebase Cloud Messaging client in Go
Firebase Cloud Messaging client in Go. Contribute to cristalhq/fcm development by creating an account on GitHub.
∏ρ؃uñçτØρ Øπτµç∑ | 👁🗨››››
Photo
Telegram
oleg_log
Если скучно, почитайте историю сооснователя Cloudflare. Талантливый был человек.
the resident genius, the guy who could focus for hours, code pouring from his fingertips while death metal blasted in his headphones. He was the master architect whose vision…
the resident genius, the guy who could focus for hours, code pouring from his fingertips while death metal blasted in his headphones. He was the master architect whose vision…
Good one. Have literally the same feedback. Cool tech but mostly useless.
https://johnjames.blog/posts/graphql-the-enterprise-honeymoon-is-over
https://johnjames.blog/posts/graphql-the-enterprise-honeymoon-is-over
johnjames.blog
GraphQL: the enterprise honeymoon is over
A production-tested take on GraphQL in enterprise systems, why the honeymoon phase fades, and when its complexity outweighs the benefits.
https://codemanship.wordpress.com/2025/12/14/the-gorman-paradox-where-are-all-the-ai-generated-apps/
Codemanship's Blog
The Gorman Paradox: Where Are All The AI-Generated Apps?
In 1950, while discussing the recent wave of flying saucer reports over lunch with colleagues at Los Alamos National Laboratory in New Mexico, physicist Enrico Fermi asked a simple question. There …
Hey look, this is just a normal programming language
https://www.phoronix.com/news/First-Linux-Rust-CVE
https://www.phoronix.com/news/First-Linux-Rust-CVE
Phoronix
Linux Kernel Rust Code Sees Its First CVE Vulnerability
The first CVE vulnerability has been assigned to a piece of the Linux kernel's Rust code.
Jokes aside. Any recommendations on image resizing in Go?
Ideally without CGO, might be a standalone service(systemd) or as a proxy.
Thanks in advance.
Ideally without CGO, might be a standalone service(systemd) or as a proxy.
Thanks in advance.
> The main challenge I’ve encountered with this in the past is that people will want to refactor the code to remove the clutter. It can take some convincing.
> This trick isn’t a panacea (nothing is), but it definitely helps
https://commaok.xyz/post/security-through-redundancy/
> This trick isn’t a panacea (nothing is), but it definitely helps
https://commaok.xyz/post/security-through-redundancy/
commaok.xyz
Security through intentional redundancy
When writing a service, it’s very easy to accidentally forget to check permissions or ownership of an object.
This code has a gaping security hole in it:
func (s *Server) deletePhoto(w http.ResponseWriter, r *http.Request) { id := r.URL.Query().Get("id")…
This code has a gaping security hole in it:
func (s *Server) deletePhoto(w http.ResponseWriter, r *http.Request) { id := r.URL.Query().Get("id")…
I was today years old when I have discovered Scala2 implicit parameters.
Absolutely disgusting. Like ultimately pro max disgusting.
The funniest thing (to me only?) it got redesigned in Scala 3 with „given” keyword.
Absolutely disgusting. Like ultimately pro max disgusting.
The funniest thing (to me only?) it got redesigned in Scala 3 with „given” keyword.
Go ahead, self-host Postgres
Love this "The real operational complexity" paragraph.
https://pierce.dev/notes/go-ahead-self-host-postgres
Love this "The real operational complexity" paragraph.
https://pierce.dev/notes/go-ahead-self-host-postgres