4 ms·
Personally I wished they had it backported to previous versions too, because it's rather convenient! What is quite sad is that we cannot add it ourselves as it
by stefanos82 1y ago
Personally I wished they had it backported to previous versions too, because it's rather convenient!
What is quite sad is that we cannot add it ourselves as it's so simple of what they have done:
func (wg *WaitGroup) Go(f func()) {
wg.Add(1)
go func() {
defer wg.Done()
f()
}()
}
- cedws 1y agoYou can wrap WaitGroup if you really want to.
- stefanos82 1y agoCan you provide an example please?
- listeria 1y agosomething like this would do it: package main import ( "sync" "time" ) type WaitGroup struct { sync.WaitGroup } func (wg *WaitGroup) Go(fn func()) { wg.Add(1) go func() { defer wg.Done() fn() }() } func main() { var wg WaitGroup wg.Go(func() { time.Sleep(1 * time.Second) }) wg.Wait() }
- stefanos82 1y agoThis is really amazing, thank you so much!
- listeria 1y agoIt's called struct embedding, there an article about it in Go by Example if you're interested: https://gobyexample.com/struct-embedding https://gobyexample.com/struct-embedding
- stefanos82 1y agoThank you @listeria, today I learned about struct embedding lol!
- genghisjahn 1y agoI rediscover this about once a year and am always so happy when I do.
- evanelias 1y agoYou can just use golang.org/x/sync/errgroup instead, which has always provided this style of use. errgroup also has other niceties like error propagation, context cancellation, and concurrency limiting.
- porridgeraisin 1y agoerrgroup cancels the whole task if even one subtask fails however. That is not desirable always.
- Groxx 1y agoIt does not, which is easy to verify from the source. Every func passed in is always run (with the exception of TryGo which is explicitly "maybe"). At best, using the optional, higher-effort errgroup.WithContext will cancel the context but still run all of your funcs. If you don't want that for one of the funcs, or some component of them, just don't use the context.
- evanelias 1y agoIf the context cancellation is undesirable, you just choose not to use WithContext, as the sibling comment mentions. You could also just make your subtask function return nil always, if you just want to get the automatic bookkeeping call pattern (like WaitGroup.Go from Golang 1.25), plus optional concurrency limiting. Also note, even if a subtask function returns an error, the errgroup Wait blocking semantics are identical to those of a WaitGroup. Wait will return the first error when it returns, but it doesn't unblock early on first error.
- Cyph0n 1y agoContext cancellation is not always desirable. I personally have been bitten multiple times by the default behavior of errgroup.
- CamouflagedKiwi 1y agoYou have to explicitly propagate the group's context if you want it to cancel. You can just not do that if you don't want - there certainly are cases for that.
- CamouflagedKiwi 1y agoThey basically don't backport anything for Go, but the quid pro quo for that is that the backwards compatibility is pretty strong so upgrades should be safe. I have seen one serious issue from it, but still it's the language I'm the most confident to do an upgrade and expect things to Just Work afterwards.