Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatic Golang goroutines

Tags:

go

In Go, if we have a type with a method that starts some looped mechanism (polling A and doing B forever) is it best to express this as:

// Run does stuff, you probably want to run this as a goroutine
func (t Type) Run() {
    // Do long-running stuff
}

and document that this probably wants to be launched as a goroutine (and let the caller deal with that)

Or to hide this from the caller:

// Run does stuff concurrently
func (t Type) Run() {
   go DoRunStuff()
}

I'm new to Go and unsure if convention says let the caller prefix with 'go' or do it for them when the code is designed to run async.

My current view is that we should document and give the caller a choice. My thinking is that in Go the concurrency isn't actually part of the exposed interface, but a property of using it. Is this right?

like image 811
Aiden Bell Avatar asked Feb 13 '15 18:02

Aiden Bell


People also ask

What is idiomatic Go?

idiom (noun): a group of words established by usage as having a meaning not deducible from those of the individual words. Idioms are hallmarks of shared values. Idiomatic Go is not something you learn from a book, it's something that you acquire by being part of a community.

How do you handle a Goroutine error?

Using a channel to return something is the only way you can guarantee to collect all return values from goroutines without overwriting them. There are multiple ways we can use the same return channels: We can use the return channel to indicate only the error. We can use it to return both the result and the error.

What means Golang?

Go (also called Golang or Go language) is an open source programming language used for general purpose. Go was developed by Google engineers to create dependable and efficient software. Most similarly modeled after C, Go is statically typed and explicit.

What are Goroutines in Golang?

A Goroutine is a function or method which executes independently and simultaneously in connection with any other Goroutines present in your program. Or in other words, every concurrently executing activity in Go language is known as a Goroutines. You can consider a Goroutine like a light weighted thread.


2 Answers

I had your opinion on this until I started writing an adapter for a web service that I want to make concurrent. I have a go routine that must be started to parse results that are returned to the channel from the web calls. There is absolutely no case in which this API would work without using it as a go routine.

I then began to look at packages like net/http. There is mandatory concurrency within that package. It is documented at the interface level that it should be able to be used concurrently, however the default implementations automatically use go routines.

Because Go's standard library commonly fires of go routines within its own packages, I think that if your package or API warrants it, you can handle them on your own.

like image 197
kwolfe Avatar answered Sep 24 '22 04:09

kwolfe


My current view is that we should document and give the caller a choice.

I tend to agree with you.

Since Go makes it so easy to run code concurrently, you should try to avoid concurrency in your API (which forces clients to use it concurrently). Instead, create a synchronous API, and then clients have the option to run it synchronously or concurrently.

This was discussed in a talk a couple years ago: Twelve Go Best Practices

Slide 26, in particular, shows code more like your first example.

I would view the net/http package as an exception because in this case, the concurrency is almost mandatory. If the package didn't use concurrency internally, the client code would almost certainly have to. For example, http.Client doesn't (to my knowledge) start any goroutines. It is only the server that does so.

In most cases, it's going to be one line of the code for the caller either way:

go Run() or StartGoroutine()

The synchronous API is no harder to use concurrently and gives the caller more options.

like image 45
zmb Avatar answered Sep 20 '22 04:09

zmb