Timing out with channels

One somewhat critical point with channels and select loops that we haven't examined particularly closely is the ability—and often necessity—to kill a select loop after a certain timeout.

Many of the applications we've written so far are long-running or perpetually-running, but there are times when we'll want to put a finite time limit on how long goroutines can operate.

The for { select { } } switch we've used so far will either live perpetually (with a default case) or wait to be broken from one or more of the cases.

There are two ways to manage interval-based tasks—both as part of the time package, unsurprisingly.

The time.Ticker struct allows for any given operation after the specified period of time. It provides C, a blocking channel that can be used to detect activity sent after that period of time; refer to the following code:

package main

import (
  "log"
  "time"
)

func main() {

  timeout := time.NewTimer(5 * time.Second)
  defer log.Println("Timed out!")

  for {
    select {
    case <-timeout.C:
      return
    default:
    }
  }

}

We can extend this to end channels and concurrent execution after a certain amount of time. Take a look at the following modifications:

package main

import (
  "fmt"
  "time"
)

func main() {

  myChan := make(chan int)

  go func() {
    time.Sleep(6 * time.Second)
    myChan <- 1
  }()

  for {
    select {
      case <-time.After(5 * time.Second):
        fmt.Println("This took too long!")
        return
      case <-myChan:
        fmt.Println("Too little, too late")
    }
  }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.109.8