fix: gc was being stupid allowing another thread to take the space it made before it could not anymore
All checks were successful
PR Check / check-and-test (pull_request) Successful in 12s
All checks were successful
PR Check / check-and-test (pull_request) Successful in 12s
This commit is contained in:
@@ -68,7 +68,7 @@ type SteamCache struct {
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func New(address string, memorySize string, memoryMultiplier int, diskSize string, diskMultiplier int, diskPath, upstream string) *SteamCache {
|
||||
func New(address string, memorySize string, diskSize string, diskPath, upstream string) *SteamCache {
|
||||
memorysize, err := units.FromHumanSize(memorySize)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -87,14 +87,14 @@ func New(address string, memorySize string, memoryMultiplier int, diskSize strin
|
||||
var mgc *gc.GCFS
|
||||
if memorysize > 0 {
|
||||
m = memory.New(memorysize)
|
||||
mgc = gc.New(m, memoryMultiplier, gc.LRUGC)
|
||||
mgc = gc.New(m, gc.LRUGC)
|
||||
}
|
||||
|
||||
var d *disk.DiskFS
|
||||
var dgc *gc.GCFS
|
||||
if disksize > 0 {
|
||||
d = disk.New(diskPath, disksize)
|
||||
dgc = gc.New(d, diskMultiplier, gc.LRUGC)
|
||||
dgc = gc.New(d, gc.LRUGC)
|
||||
}
|
||||
|
||||
// configure the cache to match the specified mode (memory only, disk only, or memory and disk) based on the provided sizes
|
||||
@@ -220,16 +220,16 @@ func (sc *SteamCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasPrefix(r.URL.String(), "/depot/") {
|
||||
// trim the query parameters from the URL path
|
||||
// this is necessary because the cache key should not include query parameters
|
||||
r.URL.Path = strings.Split(r.URL.Path, "?")[0]
|
||||
path := strings.Split(r.URL.String(), "?")[0]
|
||||
|
||||
tstart := time.Now()
|
||||
defer func() { responseTime.Observe(time.Since(tstart).Seconds()) }()
|
||||
|
||||
cacheKey := strings.ReplaceAll(r.URL.String()[1:], "\\", "/") // replace all backslashes with forward slashes shouldn't be necessary but just in case
|
||||
cacheKey := strings.ReplaceAll(path[1:], "\\", "/") // replace all backslashes with forward slashes shouldn't be necessary but just in case
|
||||
|
||||
if cacheKey == "" {
|
||||
requestsTotal.WithLabelValues(r.Method, "400").Inc()
|
||||
logger.Logger.Warn().Str("url", r.URL.String()).Msg("Invalid URL")
|
||||
logger.Logger.Warn().Str("url", path).Msg("Invalid URL")
|
||||
http.Error(w, "Invalid URL", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
@@ -258,7 +258,7 @@ func (sc *SteamCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req *http.Request
|
||||
if sc.upstream != "" { // if an upstream server is configured, proxy the request to the upstream server
|
||||
ur, err := url.JoinPath(sc.upstream, r.URL.String())
|
||||
ur, err := url.JoinPath(sc.upstream, path)
|
||||
if err != nil {
|
||||
requestsTotal.WithLabelValues(r.Method, "500").Inc()
|
||||
logger.Logger.Error().Err(err).Str("upstream", sc.upstream).Msg("Failed to join URL path")
|
||||
@@ -282,7 +282,7 @@ func (sc *SteamCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
host = "http://" + host
|
||||
}
|
||||
|
||||
ur, err := url.JoinPath(host, r.URL.String())
|
||||
ur, err := url.JoinPath(host, path)
|
||||
if err != nil {
|
||||
requestsTotal.WithLabelValues(r.Method, "500").Inc()
|
||||
logger.Logger.Error().Err(err).Str("host", host).Msg("Failed to join URL path")
|
||||
@@ -328,16 +328,17 @@ func (sc *SteamCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
size := resp.ContentLength
|
||||
|
||||
writer, err := sc.vfs.Create(cacheKey, size)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
// this is sortof not needed as we should always be able to get a writer from the cache as long as the gc is able to reclaim enough space aka the file is not bigger than the disk can handle
|
||||
ww := w.(io.Writer) // default writer to write to the response writer
|
||||
writer, _ := sc.vfs.Create(cacheKey, size) // create a writer to write to the cache
|
||||
if writer != nil { // if the writer is not nil, it means the cache is writable
|
||||
defer writer.Close() // close the writer when done
|
||||
ww = io.MultiWriter(w, writer) // write to both the response writer and the cache writer
|
||||
}
|
||||
defer writer.Close()
|
||||
|
||||
w.Header().Add("X-LanCache-Status", "MISS")
|
||||
|
||||
io.Copy(io.MultiWriter(w, writer), resp.Body)
|
||||
io.Copy(ww, resp.Body)
|
||||
|
||||
logger.Logger.Info().
|
||||
Str("key", cacheKey).
|
||||
|
||||
@@ -13,7 +13,7 @@ func TestCaching(t *testing.T) {
|
||||
|
||||
os.WriteFile(filepath.Join(td, "key2"), []byte("value2"), 0644)
|
||||
|
||||
sc := New("localhost:8080", "1G", 10, "1G", 100, td, "")
|
||||
sc := New("localhost:8080", "1G", "1G", td, "")
|
||||
|
||||
w, err := sc.vfs.Create("key", 5)
|
||||
if err != nil {
|
||||
@@ -84,7 +84,7 @@ func TestCaching(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCacheMissAndHit(t *testing.T) {
|
||||
sc := New("localhost:8080", "0", 0, "1G", 100, t.TempDir(), "")
|
||||
sc := New("localhost:8080", "0", "1G", t.TempDir(), "")
|
||||
|
||||
key := "testkey"
|
||||
value := []byte("testvalue")
|
||||
|
||||
Reference in New Issue
Block a user