How to use Timeouts in Golang


Timeouts play an important role when we don't want to wait for the output for some goroutines that are taking more time than what they should take. It should be noted that Go directly doesn't support timeouts, but we can implement them without any difficulty.

Let's suppose we have a case where we want to receive some value from a channel ch, but we don't want to wait for more than 3 seconds for the value to arrive. If we get the output after the required 3 seconds, then we want to discard it and print a different message instead of waiting for the output for a longer period of time.

Example 1

Let's first explore a simple case where we are getting output from a function after a longer period of time.

Consider the code shown below.

package main

import (
   "fmt"
   "time"
)

func timeConsuming() string {
   time.Sleep(5 * time.Second)
   return "The timeConsuming() function has stopped"
}

func main() {
   currentChannel := make(chan string, 1)

   go func() {
      text := timeConsuming()
      currentChannel <- text
   }()

   select {
   case res := <-currentChannel:
      fmt.Println(res)
   }
   fmt.Println("Main function exited!")
}

In the above code, we have a function named timeConsuming() which denotes the case of a function that might return a specific value after a longer or desired period of time. An example would be a web request where fetching data is taking too much time and the user is getting frustrated.

Inside the main function in the above code, we have a buffered channel and then we are waiting for the data to arrive with the help of the select statement. So, in the above case, the entire code would have to wait until the function timeConsuming() completes its working.

Output

If we run the above code with the command go run main.go then we will get the following output.

The timeConsuming() function has stopped
Main function exited!

Example 2

Now, let's assume that we don't want to wait for the function timeConsuming() to complete its execution. In that case, we can use the After() function of the time package.

Syntax

The syntax of the After() function is,

func After(d Duration) −- chan Time

The After function waits for d duration to finish and then it will return the current time on a channel.

Consider the code shown below where we make use of the After function to register a timeout.

package main

import (
   "fmt"
   "time"
)

func timeConsuming() string {
   time.Sleep(5 * time.Second)
   return "The timeConsuming() function has stopped"
}

func main() {
   currentChannel := make(chan string, 1)

   go func() {
      text := timeConsuming()
      currentChannel <- text
   }()

   select {
   case res := <-currentChannel:
      fmt.Println(res)
   case <-time.After(3 * time.Second):
      fmt.Println("Out of time :(")
   }
   fmt.Println("Main function exited!")
}

Output

If we run the above code with the command go run main.go then we will get the following output.

Out of time :(
Main function exited!

Updated on: 01-Nov-2021

3K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements