GOLANG USES Context to implement methods of passing values timeouts and cancellations

  • 2020-06-23 00:34:29
  • OfStack

After GO1.7, the context. Context was added to realize the management of goroutine.

Context Basic usage Reference GOLANG USES Context to manage associations goroutine.

In fact, Context also does a very important job of setting timeouts. For example, if we have an API designed like this:


type Packet interface {
  encoding.BinaryMarshaler
  encoding.BinaryUnmarshaler
}

type Stack struct {
}
func (v *Stack) Read(ctx context.Context) (pkt Packet, err error) {
  return
}

1 Common use is to create context and then call the interface:


ctx,cancel := context.WithCancel(context.Background())
stack := &Stack{}
pkt,err := stack.Read(ctx)

Then, it itself can support cancellation and timeout, that is, if the user needs to cancel, such as sent SIGINT signal, the program needs to exit, you can call cancel after receiving the signal:


sc := make(chan os.Signal, 0)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM)
go func() {
  for range sc {
    cancel()
  }
}()

If a timeout is required, the API does not need to be changed, just set the timeout before the call:


ctx,cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
pkt,err := stack.Read(ctx)

If a program is running, such as Read waiting, then it should run without human intervention. A human intervention that requires cancellation, such as upgrading a program or stopping a service, is a cancellation. Timeouts, usually 1, are the system's policy, because you can't wait 1 straight, you need to terminate the service at 1 fixed time when there is no response. In fact, context supports both of these very well without affecting the logic of Read itself. In Read, you only need to pay attention to whether context is Done:


func (v *Stack) Read(ctx context.Context) (pkt Packet, err error) {
  select {
  // case <- dataChannel: // Parse packet from data channel.
  case <- ctx.Done():
    return nil,ctx.Err()
  }
  return
}

This is why context has been accepted as a standard library package, very powerful and easy to use, but very simple. Line context, deep work and name.

In addition, Context can also pass the Key-ES47en object of the context. For example, we want the related goroutine to print a simplified CID in the log, so we can use ES50en.WithValue, refer to ES52en-ES53en-ES54en /logger.


Related articles: