Files
2026-05-20 13:27:48 -06:00

54 lines
1.2 KiB
Go

package cache
import (
"os"
"path/filepath"
)
func (c *Cache) getStream(relPath string) (*inFlight, *os.File, error) {
// lock the map
c.inFlightMu.Lock()
defer c.inFlightMu.Unlock()
// download in progress connect new stream to existing download
if flight, ok := c.inFlight[relPath]; ok {
f, err := c.cr.Open(flight.tmpPath)
if err != nil {
return nil, nil, err
}
return flight, f, nil
}
// download not in progress, setup new download and stream
// make sure the dir structure exists
if err := c.cr.MkdirAll(filepath.Dir(relPath), 0750); err != nil {
return nil, nil, err
}
// use a tmp file for the initial fetch in case it fails
tmpPath := relPath + ".tmp"
tmpFile, err := c.cr.Create(tmpPath)
if err != nil {
return nil, nil, err
}
flight := &inFlight{
contentLength: 0,
headerReady: make(chan struct{}),
tmpPath: tmpPath,
done: make(chan struct{}),
}
c.inFlight[relPath] = flight
// spin off a downloading func so we can return the file handler
// downloadWrangle takes ownership of tmpFile and closes it.
go c.downloadWrangle(relPath, flight, tmpFile)
f, err := c.cr.Open(flight.tmpPath)
if err != nil {
return nil, nil, err
}
return flight, f, nil
}