|
|
@@ -1,8 +1,19 @@
|
|
|
# Лекция 1. Контексты
|
|
|
|
|
|
+## Оглавление
|
|
|
+
|
|
|
+- [Лекция 1. Контексты](#лекция-1-контексты)
|
|
|
+ - [Оглавление](#оглавление)
|
|
|
+ - [Что это такое](#что-это-такое)
|
|
|
+ - [Зачем нужно](#зачем-нужно)
|
|
|
+ - [Примеры использования](#примеры-использования)
|
|
|
+ - [Создание глобального контекста](#создание-глобального-контекста)
|
|
|
+ - [Дочерний контекст с простой отменой](#дочерний-контекст-с-простой-отменой)
|
|
|
+ - [Дочерний контекст с таймаутом внешнего ресурса](#дочерний-контекст-с-таймаутом-внешнего-ресурса)
|
|
|
+
|
|
|
## Что это такое
|
|
|
|
|
|
-Передача данных от обработчика к обработчику требует сохранения промежуточного состояния -- контекста.
|
|
|
+Передача данных от обработчика к обработчику требует сохранения промежуточного состояния -- контекста. Контекст можно расширять или сужать, но по частям он смысла не имеет.
|
|
|
|
|
|
Контекст -- весь необходимый набор данных для выполнени операций.
|
|
|
|
|
|
@@ -14,8 +25,71 @@
|
|
|
|
|
|
## Примеры использования
|
|
|
|
|
|
-Создание глобального контекста
|
|
|
+### Создание глобального контекста
|
|
|
+
|
|
|
+```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
|
|
|
+}
|
|
|
|
|
|
-```golang
|
|
|
-ctxBg = context.Background()
|
|
|
```
|