Middle
Какви възможности предоставя създаването на дъщерен контекст на данни в Go?
sobes.tech AI
Отговор от AI
Създаването на дъщерен контекст (чрез context.WithCancel, context.WithDeadline, context.WithTimeout, context.WithValue) предоставя следните възможности:
- Отмяна: Позволява да се отменят операциите, стартирани в дъщерния контекст, без да се влияе на родителския. Това се постига чрез извикване на функцията за отмяна, която се връща при създаването на контекста.
- Времеви лимит / Deadline: Ограничават времето за изпълнение на операциите. Ако времето изтече преди завършването на операцията, контекстът автоматично се отменя.
- Пренасяне на стойности: Позволява пренасянето на специфични за заявката или операцията стойности надолу по веригата на извиквания (например, идентификатор на заявката, данни за автентикация), без да се променят подписите на функциите.
- Иерархия: Създава йерархична структура от контексти. Отмяната на родителския контекст автоматично отменя всички негови дъщерни контексти.
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Родителски контекст, който ще бъде отменен след 3 секунди
parentCtx, cancelParent := context.WithTimeout(context.Background(), 3*time.Second)
defer cancelParent() // Уверете се, че родителският контекст ще бъде отменен
// Създаване на дъщерен контекст с отменяне
childCtx, cancelChild := context.WithCancel(parentCtx)
defer cancelChild() // Уверете се, че дъщерният контекст ще бъде отменен
// Функция, която чака отменяване на контекста
go func(ctx context.Context) {
select {
case <-ctx.Done():
// Този блок ще се изпълни, когато контекстът бъде отменен
fmt.Println("Дъщерен goroutine отменен:", ctx.Err())
}
}(childCtx) // Предаване на дъщерния контекст към goroutine
// Изкуствено забавяне за демонстрация на отмяна
time.Sleep(5 * time.Second)
fmt.Println("Програмата е приключила")
}
В този пример, родителският контекст с таймаут от 3 секунди автоматично ще отменя дъщерния контекст, което ще доведе до приключване на goroutine. Дъщерният контекст може също да бъде отменен ръчно чрез извикване на cancelChild(), преди изтичането на таймаута на родителския контекст.