Live data from Hacker News

Conc: Better Structured Concurrency for Go

github.com

91–100 of 162 posts

Re: Conc: Better Structured Concurrency for Go

#91
post #72

Earlier quoted context omitted.

x == y can panic if interface values contain incomparable fields in unexported nested structs, how would I check for that? Should we let it become a query of death and bet thousands of peers’ jobs on it never happening?

don't do that? this kind of thing is why deepcompare exists to begin with

I can nag everyone to use reflect.DeepEqual and live with some false negatives, but maps always use k1 == k2.

Re: Conc: Better Structured Concurrency for Go

#92
post #61

Earlier quoted context omitted.

I literally started drafting my own structured concurrency proposal for Go 2 today, due to exactly the same frustrations you mention. Such a coincidence, and thanks for writing this lib. I will most certainly use it. Please could you tell me if you have any thoughts on how to integrate these ideas into the language? One thing I think should be solved (and that appears not addressed by your lib?) is the function color…

> I would really, really love if context was implicit and universal cancel/deadline mechansim, all the way down to IO. I don't think this is an improvement. Implicit behavior is difficult to identify and reason about. The only criticism of context that seems valid to me, aside from arbitrary storage being a huge antipattern, is that it was added long after nearly the entire standard library was authored, and it's usa…

It may not have sounded like it, but I agree with your philosophy entirely as the most important factor for language design. It’s also a big reason for why I prefer Go.

However, I also believe there are a few situations where explicitness should step aside. Go already breaks these rules for memory management - it has a GC, simply because it outweighs the benefits of explicitness. I argue that haphazard concurrency is comparable to manual memory management when it comes to both footguns and boilerplate, so I truly think it’s worth entertaining these ideas. That said, I can’t even back such a proposal myself, without first having it in hand and carefully studying it or even playing with it.

As for context, I’d like to have it trimmed down to ONLY cancelation and timeouts, possibly with user-provided errors (see Go1.20 cancel cause in exp). It shouldn’t have values at all. The reasons for the implicitness though, in order of importance:

1. Offer the caller to time out IO if the callee isn’t context aware or has forgotten to set a deadline. The majority of 3p library code I’ve seen makes such mistakes all the time, leading to socket leaks and the inability to tear down goroutines correctly.

2. To prevent the function coloring problem, which introduces substantial boilerplate duplication.

Re: Conc: Better Structured Concurrency for Go

#93

Earlier quoted context omitted.

You should rarely reach for panic. Panics are not like exceptions, really. It's very frowned upon for panics to pass API boundaries. Use errors always, unless the state of the world is irrecoverably broken. It's difficult to come up with examples of when this may be the case. Often it's a "you're holding it wrong" kind of thing. For example, a common idiom is wrapping something like func Parse(s string) (Foo, error)…

Errors don't have stack traces so they're unusable. And I see nothing wrong with handling panics. They're the same exceptions. I got SQL exception, I panic, handler catches panic, logs its stacktrace and returns HTTP 500. Awesome and no boring error handling.

It's fine to dislike Go's philosophy on error handling, but in order to save you and your co-workers a lot of headache down the road, I'd recommend you just use another language. This is not something you want to do in Go and very few folks who program in Go would be happy to work with that style of code.

In case you actually are interested in Go's take on stack traces: You are intended to annotate your errors so you can build your own stack traces with whatever information you want. This leads to better error messages because additional context (values of things) can be logged with your custom stack trace.

Re: Conc: Better Structured Concurrency for Go

#94
post #72

Earlier quoted context omitted.

don't do that? this kind of thing is why deepcompare exists to begin with

I can nag everyone to use reflect.DeepEqual and live with some false negatives, but maps always use k1 == k2.

There are also significant performance and behavior differences between the two.

They are not inter-changeable, nor can one replace the other.

Re: Conc: Better Structured Concurrency for Go

#95

Earlier quoted context omitted.

Errors don't have stack traces so they're unusable. And I see nothing wrong with handling panics. They're the same exceptions. I got SQL exception, I panic, handler catches panic, logs its stacktrace and returns HTTP 500. Awesome and no boring error handling.

It's fine to dislike Go's philosophy on error handling, but in order to save you and your co-workers a lot of headache down the road, I'd recommend you just use another language. This is not something you want to do in Go and very few folks who program in Go would be happy to work with that style of code. In case you actually are interested in Go's take on stack traces: You are intended to annotate your errors so you…

Do you suggest me to annotate my errors with "file:line" strings? Do you suggest me to grep source files with error messages to deduce stack trace? Because that's what I'm doing right now when I have to deal with stacktrace-less errors and it's not pleasant.

Re: Conc: Better Structured Concurrency for Go

#96

Just took a glance but it seems like this is exactly the kind of project I saw coming out of generics going live. I was really surprised to see how subtly hard go concurrency was to do right when initially learning it. Something like this that formalizes patterns and keeps you from leaking goroutines / deadlocking without fuss is great.

Its was initially something that surprised me about Go. It was famous for good concurrency and yet compared to many functional languages and contemporary OO languages it had a lot of foot guns. There is a lot of repetition of code that even in languages like Java had long been made common. Go seems to lack obvious concurrency abstractions. When they announced generics the first thing I did with it was rewrite my comm…

The Java Stream API is pretty awesome, it's my biggest wishlist item for Go.

Re: Conc: Better Structured Concurrency for Go

#98

Just took a glance but it seems like this is exactly the kind of project I saw coming out of generics going live. I was really surprised to see how subtly hard go concurrency was to do right when initially learning it. Something like this that formalizes patterns and keeps you from leaking goroutines / deadlocking without fuss is great.

Its was initially something that surprised me about Go. It was famous for good concurrency and yet compared to many functional languages and contemporary OO languages it had a lot of foot guns. There is a lot of repetition of code that even in languages like Java had long been made common. Go seems to lack obvious concurrency abstractions. When they announced generics the first thing I did with it was rewrite my comm…

> It was famous for good concurrency

That’s because people confuse “easy” and “good”.

Go has easy concurrency, but it’s not good. The opposite really. It’s at best the similar problematic model you get in other, older, procedural / oo langages. At worst it’s a lot worse given how difficult it is (and even more so was before generics) to build abstractions and concurrent data structures.

Re: Conc: Better Structured Concurrency for Go

#99
post #7

The WaitGroup looks suspiciously like errgroup, which even has the .WithMaxGoroutines() functionality: https://pkg.go.dev/golang.org/x/sync/errgroup > A frequent problem with goroutines in long-running applications is handling panics. A goroutine spawned without a panic handler will crash the whole process on panic. This is usually undesirable. In go land, this seems desirable. Recoverable errors should be propagated…

> The WaitGroup looks suspiciously like errgroup I heavily used errgroup before creating conc, so the design is likely strongly influenced by that of errgroup even if not consciously. Conc was partially built to address the shortcomings of errgroup (from my perspective). Probably worth adding a "prior art" section to the README, but many of the ideas in conc are not unique. > In go land, this seems desirable. I mostl…

A "prior art" section is especially useful for people evaluating your library!

Re: Conc: Better Structured Concurrency for Go

#100

Earlier quoted context omitted.

It's fine to dislike Go's philosophy on error handling, but in order to save you and your co-workers a lot of headache down the road, I'd recommend you just use another language. This is not something you want to do in Go and very few folks who program in Go would be happy to work with that style of code. In case you actually are interested in Go's take on stack traces: You are intended to annotate your errors so you…

Do you suggest me to annotate my errors with "file:line" strings? Do you suggest me to grep source files with error messages to deduce stack trace? Because that's what I'm doing right now when I have to deal with stacktrace-less errors and it's not pleasant.

The idea is you `fmt.Errorf("invalid foo, given '%v' important argument: %w", arg, err)` and you end up with errors like:

    http GET /abc: start DB: run migration COOL_MIGRATION: invalid foo, given 'bar' important argument: file not exist
If done well, you might be able to fully diagnose the bug just by reading the error, since it may include every bit of relevant context. If not, you can grep for the original error substrings to find the relevant code.

The point is that these aren't just Xs on a map telling you where something went wrong, they're supposed to be meaningful descriptions of why something went wrong.

Post reply on HN