streaming with custom reader and multiple client functionality
This commit is contained in:
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
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{
|
||||
tmpPath: tmpPath,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user