Повторное использование родительского контекста с context.WithTimeout с новым тайм-аутом
Привет, я новичок в go
. Мне было интересно, если можно повторно использовать родительский контекст для создания нескольких context.withTimeout (). Обоснованием было бы то, где я должен вызывать несколько сетевых запросов последовательно и хотел бы установить таймаут для каждого запроса одновременно, используя контекст родителя.
Обоснование
Когда контекст родителя отменяется, все сделанные запросы также отменяются.
Проблема
В приведенном ниже коде показан пример, в котором LongProcess
является запросом сети. Однако контекст закрывается, прежде чем второй вызов LongProcess
может быть выполнен с помощью context deadline exceeded
.
В документации withDeadline
говорится The returned context's Done channel is closed when the deadline expires, when the returned cancel function is called, or when the parent context's Done channel isclosed, whichever happens first.
Так что, если это так, есть ли способ, где я могу сбросить таймер для withTimeout? Или мне нужно создавать новый контекст context.Background()
для каждого запроса? Это будет означать, что родительский контекст не будет передан. : (
// LongProcess refers to a long network request
func LongProcess(ctx context.Context, duration time.Duration, msg string) error {
c1 := make(chan string, 1)
go func() {
// Simulate processing
time.Sleep(duration)
c1 <- msg
}()
select {
case m := <-c1:
fmt.Println(m)
return nil
case <-ctx.Done():
return ctx.Err()
}
}
func main() {
ctx := context.Background()
t := 2 * time.Second
ctx, cancel := context.WithTimeout(ctx, t)
defer cancel()
// Simulate a 2 second process time
err := LongProcess(ctx, 2*time.Second, "first process")
fmt.Println(err)
// Reusing the context.
s, cancel := context.WithTimeout(ctx, t)
defer cancel()
// Simulate a 1 second process time
err = LongProcess(s, 1*time.Second, "second process")
fmt.Println(err) // context deadline exceeded
}