lesson01.md 3.7 KB

Лекция 1. Контексты

Оглавление

Что это такое

Передача данных от обработчика к обработчику требует сохранения промежуточного состояния -- контекста. Контекст можно расширять или сужать, но по частям он смысла не имеет.

Контекст -- весь необходимый набор данных для выполнени операций.

Зачем нужно

  • накопление, удаление обрабатываемых данных между запросами;
  • контроль родительского процесса за дочерними;
  • охрана запросов в реальном времени за внешними ресурсами.

Примеры использования

Создание глобального контекста

ctxBg := context.Background()

Глобальный контекст использовать нельзя!

Почитать про API

Дочерний контекст с простой отменой

Дочерний контекст с простой отменой:

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
    }
}

Дочерний контекст с таймаутом внешнего ресурса

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
}