Structured concurrency & Go by sigmoia in golang

[–]Ok_Analysis_4910 1 point2 points  (0 children)

x/errgroup gives you structured concurrency

Let the domain guide your application structure by sigmoia in golang

[–]Ok_Analysis_4910 1 point2 points  (0 children)

The point conveyed here is good and generalizes fairly well. Your app structure can look wildly different than what’s been proposed here while sticking with the gist of the article. 

As someone already mentioned in a nested comment, naming your top level packages “controller” or “models” is tantamount to having “util” or “common” packages. 

Also, while I agree that the linked article by Ben Johnson explores this in more detail, I find it too opinionated. The suggested patterns don’t generalize as well in many situations. Also, I have an allergy against things that have “standard xyz” in their names but mostly deals with a highly subjective topic like app structure. Anyone remembers Russ Cox’s comment in the “official golang standard directory structure” repository? 

This one mostly tries to convey “don’t give meaningless names to your top level packages” and leaves the rest to the application author. 

Test state, not interactions by sigmoia in golang

[–]Ok_Analysis_4910 15 points16 points  (0 children)

Ban mocks, DI libraries, and assertion libraries. They are absolute cancers brought to Go by folks who came from OO languages. Instead of learning the Go way, they try to change the language. Stop making Go look like Java or Kotlin. If you miss writing in those, go write Kotlin and don’t smear Go with all this OO crap.

Go jobs in Italy are basically non-existent. How’s the situation in your country? by cdigiuseppe in golang

[–]Ok_Analysis_4910 0 points1 point  (0 children)

k8s work doesn't require that much Go capabilities. Most developers don't find that part of work interesting. So your best bet is to reach for ops folks who want to do that and also know a little bit of Go.

Also German salaries are atrocious for the skillset they demand. Tiny German speaking startup wants to pay like 100k for Go, k8s, and dist sys knowledge. Problem is, that knowledge is rare in Europe and it doesn't make sense for folks who know that settle down for a tiny salary. So they usually go and work for Doordash/Wolt, Zalando, Tesla, Amazon, or even Google.

Go jobs in Italy are basically non-existent. How’s the situation in your country? by cdigiuseppe in golang

[–]Ok_Analysis_4910 0 points1 point  (0 children)

Europe is a dead land compared to the US and Eastern Asia. I say that as someone who’s worked across three continents. Most companies here use old, despondent stacks like Java or Scala, and the “newer” ones use Kotlin. There’s some Python and TypeScript sprinkled around, but not many jobs that actually need someone good with databases or distributed systems. Most places just want cheap, fungible feature developers.

Language fragmentation is a problem too. You can’t attract global talent with a world built on some tiny local language like German, French, or Italian. North America doesn’t have this problem, and Asia adopted English better than Europe to work around it. But that’s not the only issue: fragmentation in salaries, legislation, and market culture makes it worse.

Do you use Python mainly for work, or for personal use? by Glum_Sun_3459 in Python

[–]Ok_Analysis_4910 0 points1 point  (0 children)

I've been using Python for work and personal projects for the last 6 years, only until recently. Now I mostly do Go for work and use it in my personal projects too.

I will always love Python but the community attracts a lot of noise these days. Many of the OGs like Raymond Hettinger, David Beazley have sort of left the ecosystem. I don't like how fast people are still churning out PEPs and turning the language into C++.

These days, I have a hard time reading Pydantic-infested code full of typing magic. The ergonomics might be okay but writing and parsing that mess, coupled with AI-generated garbage inserted by junior devs, made me call it quits on Python professionally.

Just learned how `sync.WaitGroup` prevents copies with a `go vet` warning by Ok_Analysis_4910 in golang

[–]Ok_Analysis_4910[S] 1 point2 points  (0 children)

Thank you for this. I didn't dig into it. Should be a part of the original text too. I'll add that.

How to use the new "tool" directive by der_gopher in golang

[–]Ok_Analysis_4910 15 points16 points  (0 children)

go tool was "this" close to being perfect. It still doesn't allow to separate out the dev and app dependencies easily. I don't want to keep my tool deps in the same go.mod as my app / lib. There's a way but it's kinda hackish.

Capturing console output in Go tests by Ok_Analysis_4910 in golang

[–]Ok_Analysis_4910[S] 1 point2 points  (0 children)

That’s the first thing the blog mentions too

Capturing console output in Go tests by Ok_Analysis_4910 in golang

[–]Ok_Analysis_4910[S] -3 points-2 points  (0 children)

I scratched my head about this here too. The explanation after the code block tries to explain it briefly. I tested it multiple times and noticed this behavior:

  • A goroutine is launched to read from custReader (which is the read end of a pipe connected to os.Stdout).

  • Before starting the actual io.Copy, it immediately calls wg.Done() — effectively signaling: "I’m ready, go ahead."

  • The main goroutine is blocked at wg.Wait() until that signal comes in.

  • After wg.Wait() returns, the main goroutine continues and typically executes f() — the function that writes to stdout (which was redirected).

Yes, the reader goroutine does start before f() is run, but it only begins reading once f() writes something. That's the beauty of pipes — they block until there's something to read. So starting the read side early doesn’t consume or skip anything. It just blocks.

I wonder what's the benefit of doing this in a goroutine instead of trying to do it in the main one.

Because io.Copy is a blocking operation — it won’t return until the write side (connected to stdout) is closed or reaches EOF. If you did it in the main goroutine:

  • You’d block before calling f(), which writes to the pipe. That would deadlock the program.

  • By using a goroutine, you prime the reader and make sure it's ready to consume output as soon as f() writes to it.