Тип context.CancelCauseFunc

Тип context.CancelCauseFunc представляет собой функцию, которая отменяет контекст и позволяет указать причину отмены. Этот тип является расширением обычной context.CancelFunc и возвращается функциями context.WithCancelCause, context.WithTimeoutCause и context.WithDeadlineCause. При вызове этой функции контекст отменяется, а переданная ошибка становится доступной через функцию context.Cause.

Синтаксис

gotype CancelCauseFunc func(cause error)

Тип CancelCauseFunc определяет функцию, которая принимает один параметр - ошибку cause, описывающую причину отмены. Эта функция не возвращает никаких значений.

Пример с WithCancelCause

Давайте создадим контекст с возможностью отмены по причине и отменим его с указанием конкретной ошибки:

gopackage main

import (
  "context"
  "fmt"
  "errors"
)

func main() {
  ctx, cancel := context.WithCancelCause(context.Background())
  
  // Отменяем контекст с указанием причины
  cancel(errors.New("operation cancelled by user"))
  
  // Проверяем причину отмены
  cause := context.Cause(ctx)
  fmt.Println(cause)
}

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

go"operation cancelled by user"

Пример с WithTimeoutCause

Рассмотрим пример использования CancelCauseFunc с таймаутом, где причиной отмены становится превышение времени:

gopackage main

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

func main() {
  ctx, cancel := context.WithTimeoutCause(
    context.Background(),
    10*time.Millisecond,
    errors.New("timeout exceeded"),
  )
  defer cancel()
  
  time.Sleep(20 * time.Millisecond)
  
  // Проверяем причину отмены
  cause := context.Cause(ctx)
  fmt.Println(cause)
}

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

go"timeout exceeded"

Пример проверки причины

Покажем, как можно проверить причину отмены с помощью функции context.Cause:

gopackage main

import (
  "context"
  "fmt"
  "errors"
)

func main() {
  ctx, cancel := context.WithCancelCause(context.Background())
  
  // Создаем две возможные причины
  errUserCancel := errors.New("user cancelled")
  errTimeout := errors.New("timeout reached")
  
  // Отменяем с одной из причин
  cancel(errUserCancel)
  
  // Проверяем причину
  cause := context.Cause(ctx)
  if cause == errUserCancel {
    fmt.Println("cancelled by user")
  } else if cause == errTimeout {
    fmt.Println("cancelled by timeout")
  } else {
    fmt.Println("cancelled by other reason")
  }
}

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

go"cancelled by user"

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

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