| <!--{ | |
| "Title": "Go Concurrency Patterns: Timing out, moving on", | |
| "Template": true | |
| }--> | |
| <p> | |
| Concurrent programming has its own idioms. A good example is timeouts. Although | |
| Go's channels do not support them directly, they are easy to implement. Say we | |
| want to receive from the channel <code>ch</code>, but want to wait at most one | |
| second for the value to arrive. We would start by creating a signalling channel | |
| and launching a goroutine that sleeps before sending on the channel: | |
| </p> | |
| {{code "/doc/progs/timeout1.go" `/timeout :=/` `/STOP/`}} | |
| <p> | |
| We can then use a <code>select</code> statement to receive from either | |
| <code>ch</code> or <code>timeout</code>. If nothing arrives on <code>ch</code> | |
| after one second, the timeout case is selected and the attempt to read from | |
| <cde>ch</cde> is abandoned. | |
| </p> | |
| {{code "/doc/progs/timeout1.go" `/select {/` `/STOP/`}} | |
| <p> | |
| The <code>timeout</code> channel is buffered with space for 1 value, allowing | |
| the timeout goroutine to send to the channel and then exit. The goroutine | |
| doesn't know (or care) whether the value is received. This means the goroutine | |
| won't hang around forever if the <code>ch</code> receive happens before the | |
| timeout is reached. The <code>timeout</code> channel will eventually be | |
| deallocated by the garbage collector. | |
| </p> | |
| <p> | |
| (In this example we used <code>time.Sleep</code> to demonstrate the mechanics | |
| of goroutines and channels. In real programs you should use <code> | |
| <a href="/pkg/time/#After">time.After</a></code>, a function that returns | |
| a channel and sends on that channel after the specified duration.) | |
| </p> | |
| <p> | |
| Let's look at another variation of this pattern. In this example we have a | |
| program that reads from multiple replicated databases simultaneously. The | |
| program needs only one of the answers, and it should accept the answer that | |
| arrives first. | |
| </p> | |
| <p> | |
| The function <code>Query</code> takes a slice of database connections and a | |
| <code>query</code> string. It queries each of the databases in parallel and | |
| returns the first response it receives: | |
| </p> | |
| {{code "/doc/progs/timeout2.go" `/func Query/` `/STOP/`}} | |
| <p> | |
| In this example, the closure does a non-blocking send, which it achieves by | |
| using the send operation in <code>select</code> statement with a | |
| <code>default</code> case. If the send cannot go through immediately the | |
| default case will be selected. Making the send non-blocking guarantees that | |
| none of the goroutines launched in the loop will hang around. However, if the | |
| result arrives before the main function has made it to the receive, the send | |
| could fail since no one is ready. | |
| </p> | |
| <p> | |
| This problem is a textbook of example of what is known as a | |
| <a href="https://en.wikipedia.org/wiki/Race_condition">race condition</a>, but | |
| the fix is trivial. We just make sure to buffer the channel <code>ch</code> (by | |
| adding the buffer length as the second argument to <a href="/pkg/builtin/#make">make</a>), | |
| guaranteeing that the first send has a place to put the value. This ensures the | |
| send will always succeed, and the first value to arrive will be retrieved | |
| regardless of the order of execution. | |
| </p> | |
| <p> | |
| These two examples demonstrate the simplicity with which Go can express complex | |
| interactions between goroutines. | |
| </p> |