diff options
Diffstat (limited to 'tvix/nar-bridge')
-rw-r--r-- | tvix/nar-bridge/pkg/server/nar_get.go | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/tvix/nar-bridge/pkg/server/nar_get.go b/tvix/nar-bridge/pkg/server/nar_get.go index b1eb70b624f0..d31fa1fbeeab 100644 --- a/tvix/nar-bridge/pkg/server/nar_get.go +++ b/tvix/nar-bridge/pkg/server/nar_get.go @@ -117,25 +117,34 @@ func renderNar( }) if err != nil { return nil, fmt.Errorf("unable to get blob: %w", err) - } - // TODO: spin up a goroutine producing this. - data := &bytes.Buffer{} - for { - chunk, err := resp.Recv() - if errors.Is(err, io.EOF) { - break - } - if err != nil { - return nil, fmt.Errorf("read chunk: %w", err) - } - _, err = data.Write(chunk.GetData()) - if err != nil { - return nil, fmt.Errorf("buffer chunk: %w", err) + // set up a pipe, let a goroutine write, return the reader. + pR, pW := io.Pipe() + + go func() { + for { + chunk, err := resp.Recv() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + pW.CloseWithError(fmt.Errorf("receiving chunk: %w", err)) + return + } + + // write the received chunk to the writer part of the pipe + if _, err := io.Copy(pW, bytes.NewReader(chunk.GetData())); err != nil { + log.WithError(err).Error("writing chunk to pipe") + pW.CloseWithError(fmt.Errorf("writing chunk to pipe: %w", err)) + return + } } - } - return io.NopCloser(data), nil + pW.Close() + + }() + + return io.NopCloser(pR), nil }, ) if err != nil { |