Middle
Разкажи ми за случаите на използване на контекста в Go.
sobes.tech AI
Отговор от AI
Контекстът в Go се използва за управление на жизнения цикъл на заявките и контрол на изпълнението на горутините. Основните случаи на употреба:
- Отмяна: Позволява да се отменя веригата от горутини, свързана с определена заявка. Например при затваряне на връзката или при изтичане на таймаут.
- Таймаут: Настройва крайния срок за изпълнение на операцията. Ако операцията не завърши навреме, контекстът се отменя. Това предотвратява безкрайно чакане.
- Предаване на специфични за заявката данни: Позволява да се предават данни, свързани с конкретна заявка (например ID на потребител, идентификатор на трасировка), чрез веригата от функции без промяна на техните сигнатури.
Примери за употреба:
-
Отмяна по сигнал:
пакет main import ( "context" "fmt" "time" ) функция worker(ctx context.Context, id int) { за { избор { случай <-ctx.Done(): fmt.Printf("Работник %d прекъснат\n", id) връщане default: fmt.Printf("Работник %d работи...\n", id) time.Sleep(500 * time.Millisecond) } } } функция main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Гарантираме отмяна go worker(ctx, 1) go worker(ctx, 2) time.Sleep(2 * time.Second) cancel() // Отменяме контекста time.Sleep(500 * time.Millisecond) // Даваме време на горутините да приключат } -
Таймаут:
пакет main import ( "context" "fmt" "time" ) функция longOperation(ctx context.Context) error { избор { случай <-time.After(3 * time.Second): // Имитация на дълга работа fmt.Println("Операцията успешно завърши") връщане nil случай <-ctx.Done(): fmt.Println("Операцията е отменена от контекста:", ctx.Err()) връщане ctx.Err() } } функция main() { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() err := longOperation(ctx) ако ако err != nil { fmt.Println("Грешка:", err) } } -
Предаване на данни:
пакет main import ( "context" "fmt" ) type UserKey string const userIDKey UserKey = "userID" func processRequest(ctx context.Context) { userID := ctx.Value(userIDKey).(int) fmt.Printf("Обработка на заявка за потребителско ID: %d\n", userID) // Дальнейша обработка на заявката с използване на userID } func main() { ctx := context.WithValue(context.Background(), userIDKey, 123) processRequest(ctx) }