Hacker News new | past | comments | ask | show | jobs | submit login

That makes sense: channels are a way of organizing concurrent programs, not a way of organizing distributed systems. They're a tool you might use to build a persistent work queue (or, like many programmers, including people working on the Go stdlib, you might use other synchronization constructions), not a work queue themselves.



When I first learned Go, my impression (and also tutorials usually imply that) was that they are a nice elegant way to build concurrent pipelines where goroutine A sends work items to goroutine B which can, in its turn, send some work items to goroutine C etc. But in practice for robustness we prefer persistent queues for such pipelines because on power loss, a panic, or if your application is simply being killed on redeploy, your program can lose data or end up in an inconsistent state, because whatever was the in the channels is completely lost (and the work is already half done). So it leaves us with only a few use cases where they're really useful such as basic goroutine coordination. I think what you are saying is that they're a synchronization primitive akin to mutexes, atomics etc., no more no less, and I'm fine with that, but then it's not clear why then channels have a special syntax and why they are sold as one of Go's strong points, if it's just a niche synchronization primitive. The only useful case I found for them was to send an empty struct to a goroutine to signalize that there's a new work item in the persistent queue, to avoid having to poll the external queue too often. I wonder if other web devs have experience similar to ours, or maybe there are other use cases for channels we are not aware of.


The point of channels is to have communication between threads that's easier to reason about than explicit locks. Rather than, for instance, unlocking a map to update it, you treat a single thread as a "server" for that map. If you don't want to structure your programs that way, you'd just use mutexes.


In older web languages, like PHP, I would reckon it’s like making a self-http call where you don’t care about the result and just want to trigger some work elsewhere in the application async. I guess with Go channels, you’d lose out on concurrency, automatic retries (depending on infra), and debuggability — you could do the same with Go and http calls though and just drop the channels completely.

But yeah, sometimes things break. We rely on things like nginx options to retry GET requests and idempotency in the design; failing gracefully (via a shutdown callback to always return something to a caller); ensuring work is completed before writing a successful response anywhere, along with being idempotent; and, ensuring there’s observability in every long-running task.


> That makes sense: channels are a way of organizing concurrent programs, not a way of organizing distributed systems.

Exactly.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: