# Лекция 1. Контексты ## Оглавление - [Лекция 1. Контексты](#лекция-1-контексты) - [Оглавление](#оглавление) - [Что это такое](#что-это-такое) - [Зачем нужно](#зачем-нужно) - [Примеры использования](#примеры-использования) - [Создание глобального контекста](#создание-глобального-контекста) - [Дочерний контекст с простой отменой](#дочерний-контекст-с-простой-отменой) - [Дочерний контекст с таймаутом внешнего ресурса](#дочерний-контекст-с-таймаутом-внешнего-ресурса) ## Что это такое Передача данных от обработчика к обработчику требует сохранения промежуточного состояния -- контекста. Контекст можно расширять или сужать, но по частям он смысла не имеет. Контекст -- весь необходимый набор данных для выполнени операций. ## Зачем нужно - накопление, удаление обрабатываемых данных между запросами; - контроль родительского процесса за дочерними; - охрана запросов в реальном времени за внешними ресурсами. ## Примеры использования ### Создание глобального контекста ```go ctxBg := context.Background() ``` **Глобальный контекст использовать нельзя!** ### Дочерний контекст с простой отменой Дочерний контекст с простой отменой: ```go func FindRecord(ctxApp app.AppContext, numRecord string) error { ctxWork, fnCancel := context.WithCancel(ctxApp) defer fnCancel() chWork := make(chan int, 2) fnRead :=func(){ defer close(chWork) err:=file.FindRecord(numRecord) if err!=nil{ ctxApp.Cancel() } } go fnRead() select { case <-ctxApp.Done(): // Отмена контекста приложения return fmt.Errorf("FindRecord(): cancel ctxApp") // Ожидание окончания работы, всё-равно // когда-нибудь закончится так или иначе. case <-chWork: return nil } } ``` ### Дочерний контекст с таймаутом внешнего ресурса ```go func Index(ctx contextContext, request *IndexRequest)(*IndexResponse, error){ chErr := make (chan error, 2) ctxTimeout, fnCancel := cntext.WithTimeout(ctx, time.Millisecond * 500) defer fnCancel() var ( resp = &IndexResponse{} err error ) fnWork := func(){ defer close(chError) resp, err = db.Get(request.Name) if err!=nil{ chErr <- err return } } go fnWork() select { case <-ctxTimeout.Done(): // Был ли таймаут? return nil, fmt.Errorf("Index(): timeout in make response") case err<-chErr: // Была ли ошибка? if err!=nil{ eturn nil, fmt.Errorf("Index(): in make response, err=\n\t%w", err) } } return resp, nil } ```