Junior
Šta je kontekst u Go?
sobes.tech АИ
Одговор од АИ
Контекст (context.Context) у језику Go је објекат који носи рок за извршење, сигнал за отказ (cancellation signal) и податке специфичне за захтев. Користи се за управљање животним циклусом горутина и пренос информација међу њима током извршавања једног захтева/операције.
Главне карактеристике:
- Безбедан за нитеве: Може безбедно преносити између горутина.
- Имутабилан: Након креирања,
Contextсе не може променити. Производни контексти се креирају на основу родитељског. - Иерархичан: Контексти формирају дрво са кореном (
context.Background()илиcontext.TODO()). Отказ родитељског контекста доводи до отказа свих дечијих.
Главне функције пакета context:
context.Background(): Празан контекст, обично се користи у главној функцији, у врхунским захтевима или при тестирању. Никада није отказан.context.TODO(): Такође празан контекст. Користи се као замена када није познато који контекст користити, или ако функционалност контекста још није реализована.context.WithCancel(parent Context): Враћа нови дечији контекст и функцију за отказивање. Позивом функције за отказивање, овај контекст и сви његови дечији се отказују.context.WithDeadline(parent Context, deadline time.Time): Враћа дечији контекст који се аутоматски отказује када достигне датум. Такође враћа функцију за ручно отказивање.context.WithTimeout(parent Context, timeout time.Duration): Исто каоWithDeadline, али са временским ограничењем.context.WithValue(parent Context, key, val interface{}): Враћа дечији контекст са додељеном вредношћу по кључу.
Примена:
- Отказивање операција: На пример, таймаут HTTP захтева или прекид дуге операције.
- Пренос података: На пример, ID захтева за логовање, аутентификационе информације.
Пример коришћења context.WithTimeout:
package main
import (
"context"
"fmt"
"time"
)
func longRunningOperation(ctx context.Context, resultChan chan string) {
select {
case <-time.After(3 * time.Second):
// Операција успешно завршена
resultChan <- "Operation completed"
case <-ctx.Done():
// Контекст је отказан
err := ctx.Err() // Добијање разлога отказа
resultChan <- fmt.Sprintf("Operation cancelled: %v", err)
}
}
func main() {
// Креирање контекста са временским ограничењем од 2 секунде
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // Гарантује позив функције за отказивање
resultChan := make(chan string, 1)
go longRunningOperation(ctx, resultChan)
// Чекање резултата или отказа
select {
case res := <-resultChan:
fmt.Println(res)
case <-ctx.Done():
fmt.Printf("Main context done: %v\n", ctx.Err())
}
// Мало чекање да се горутина заврши ако је отказана
time.Sleep(1 * time.Second)
}
У овом примеру, longRunningOperation проверава да ли је контекст отказан. Ако временски ограничење главног контекста (2 секунде) истекне пре него што се заврши сама операција (3 секунде), горутина добија сигнал за отказ преко ctx.Done() и завршава се.