Метод context.Context.Done

Метод Done интерфейса context.Context возвращает канал, который закрывается при отмене контекста или превышении таймаута. Этот канал используется для получения сигнала об отмене и позволяет грациозно завершить работу горутин. Метод не принимает никаких параметров и возвращает канал типа <-chan struct{}.

Синтаксис

goctx.Done()

Пример

Давайте создадим контекст с отменой и обработаем сигнал от канала Done:

gopackage main

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

func main() {
  ctx, cancel := context.WithCancel(context.Background())

  go func() {
    time.Sleep(2 * time.Second)
    cancel()
  }()

  select {
  case <-ctx.Done():
    fmt.Println("Context cancelled")
  }
}

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

go"Context cancelled"

Пример

Рассмотрим пример с таймаутом. Канал Done закроется по истечении заданного времени:

gopackage main

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

func main() {
  ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
  defer cancel()

  select {
  case <-ctx.Done():
    fmt.Println("Timeout exceeded")
  }
}

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

go"Timeout exceeded"

Пример

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

gopackage main

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

func main() {
  ctx, cancel := context.WithCancel(context.Background())

  go func() {
    for {
      select {
      case <-ctx.Done():
        fmt.Println("Stopping goroutine")
        return
      default:
        fmt.Println("Working...")
        time.Sleep(500 * time.Millisecond)
      }
    }
  }()

  time.Sleep(2 * time.Second)
  cancel()
  time.Sleep(1 * time.Second)
}

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

go"Working..."
"Working..."
"Working..."
"Working..."
"Stopping goroutine"

Пример

Проверим, что канал Done не блокирует выполнение программы при отсутствии отмены:

gopackage main

import (
  "context"
  "fmt"
)

func main() {
  ctx := context.Background()

  select {
  case <-ctx.Done():
    fmt.Println("This will not print")
  default:
    fmt.Println("No cancellation signal")
  }
}

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

go"No cancellation signal"

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

  • метод Context,
    который возвращает контекст
  • метод Err,
    который возвращает ошибку отмены контекста
  • метод Deadline,
    который возвращает время дедлайна контекста
  • функцию WithCancel,
    которая создает контекст с возможностью отмены