У меня есть эта текущая функция, которая изначально не учитывала контекст.
func (s *Service) ChunkUpload(r *multipart.Reader) error {
chunk, err := s.parseChunk(r)
if err != nil {
return fmt.Errorf("failed parsing chunk %w", err)
}
if err := os.MkdirAll(chunk.UploadDir, 02750); err != nil {
return err
}
if err := s.saveChunk(chunk); err != nil {
return fmt.Errorf("failed saving chunk %w", err)
}
return nil
}
Я обновил вызов метода, чтобы теперь он принимал context.Context
в качестве первого аргумента. Моя основная цель - завершить и вернуть функцию, как только контекст будет отменен.
Моя первоначальная реализация была такой.
func (s *Service) ChunkUpload(ctx context.Context, r *multipart.Reader) error {
errCh := make(chan error)
go func() {
chunk, err := s.parseChunk(r)
if err != nil {
errCh <- fmt.Errorf("failed parsing chunk %w", err)
return
}
if err := os.MkdirAll(chunk.UploadDir, 02750); err != nil {
errCh <- err
return
}
if err := s.saveChunk(chunk); err != nil {
errCh <- fmt.Errorf("failed saving chunk %w", err)
return
}
}()
select {
case err := <-errCh:
return err
case <-ctx.Done():
return ctx.Err()
}
}
Однако, как я думал о выполнении кода Я понял, что это не достигает моей цели. Поскольку все функции logi c находятся в отдельной подпрограмме go, даже если контекст отменяется, и я возвращаю ChunkUpload
раньше, код внутри подпрограммы go будет продолжать выполняться, поэтому на самом деле не будет отличаться от исходного кода. .
Следующее, хотя было нормально, просто передайте контекст всем внутренним функциям, таким как s.parseChunk
и s.saveChunk
, но этот вариант также не кажется правильным, поскольку мне нужно было бы реализовать отмены в каждой функции. Каким будет правильный способ рефакторинга этой исходной функции, чтобы она была зависимой от контекста и завершалась, как только контекст отменяется?