Функция context.WithDeadlineCause

Функция context.WithDeadlineCause создает новый контекст, который отменяется автоматически, когда время достигает указанного дедлайна, либо при явном вызове функции отмены. В отличие от context.WithDeadline, эта функция позволяет передать причину отмены в виде ошибки, которая будет возвращена методом context.Err после отмены контекста. Первым параметром функция принимает родительский контекст, вторым - время дедлайна, третьим - ошибку-причину.

Синтаксис

goctx, cancel := context.WithDeadlineCause(parent, d, cause)

Пример

Давайте создадим контекст с дедлайном на 100 миллисекунд и причиной "deadline exceeded", а затем проверим его отмену:

gopackage main

import (
  "context"
  "fmt"
  "time"
)

func main() {
  deadline := time.Now().Add(100 * time.Millisecond)
  cause := fmt.Errorf("deadline exceeded")
  ctx, cancel := context.WithDeadlineCause(context.Background(), deadline, cause)
  defer cancel()

  select {
  case <-ctx.Done():
    fmt.Println(ctx.Err())
  case <-time.After(200 * time.Millisecond):
    fmt.Println("timeout")
  }
}

Результат выполнения кода:

go"deadline exceeded"

Пример

Давайте создадим контекст с дедлайном и явно отменим его до наступления дедлайна:

gopackage main

import (
  "context"
  "fmt"
  "time"
)

func main() {
  deadline := time.Now().Add(1000 * time.Millisecond)
  cause := fmt.Errorf("deadline exceeded")
  ctx, cancel := context.WithDeadlineCause(context.Background(), deadline, cause)

  cancel()
  
  select {
  case <-ctx.Done():
    fmt.Println(ctx.Err())
  case <-time.After(100 * time.Millisecond):
    fmt.Println("timeout")
  }
}

Результат выполнения кода:

go"context canceled"

Пример

Давайте используем созданный контекст для выполнения операции с ограничением времени:

gopackage main

import (
  "context"
  "fmt"
  "time"
)

func main() {
  deadline := time.Now().Add(50 * time.Millisecond)
  cause := fmt.Errorf("deadline exceeded")
  ctx, cancel := context.WithDeadlineCause(context.Background(), deadline, cause)
  defer cancel()

  select {
  case <-time.After(100 * time.Millisecond):
    fmt.Println("operation completed")
  case <-ctx.Done():
    fmt.Println(ctx.Err())
  }
}

Результат выполнения кода:

go"deadline exceeded"

Смотрите также

  • функцию context.WithTimeoutCause,
    которая создает контекст с таймаутом и причиной
  • функцию context.WithCancelCause,
    которая создает контекст с возможностью отмены и указанием причины
  • функцию context.Cause,
    которая возвращает причину отмены контекста
  • функцию context.Context.Err,
    которая возвращает ошибку завершения контекста