diff --git a/pkg/fs/file.go b/pkg/fs/file.go index acfc50e..e6db254 100644 --- a/pkg/fs/file.go +++ b/pkg/fs/file.go @@ -53,7 +53,7 @@ func (f *File) Preload(ctx context.Context, fin func(), errf func(), stop func() defer f.Close() if f.offline { log.V(2).Error(errors.New("no preload in offline mode"), "error preloading file") - fin() + errf() return } if f.md.FullyCached() { diff --git a/pkg/fs/preload.go b/pkg/fs/preload.go index 2904ea9..6b709ef 100644 --- a/pkg/fs/preload.go +++ b/pkg/fs/preload.go @@ -5,6 +5,7 @@ package fs import ( "context" "sync" + "time" "github.com/go-logr/logr" "golang.org/x/exp/slices" @@ -44,12 +45,23 @@ func (q *queue) Remove(name string) { } } +func (q *queue) GetPreload(name string) *Preload { + for _, p := range *q { + if p.Name == name { + return p + } + } + return nil +} + type Preload struct { ph *PreloadHandler + delay time.Duration Name string cancel func() Prio int Status int + Errc int Running bool } @@ -113,7 +125,7 @@ func (ph *PreloadHandler) Preload(name string, prio int) { func (ph *PreloadHandler) schedule() { for i := 0; i < len(ph.q); i++ { if i < ph.max { - ph.q[i].start() + go ph.q[i].start() } else { ph.q[i].stop(true) } @@ -124,10 +136,14 @@ func (p *Preload) start() { if p.Running { return } + if p.delay != 0 { + time.Sleep(p.delay) + } name := p.Name file, err := p.ph.fs.Open(name) if err != nil { p.ph.log.Error(err, "error staring next preload", "file", name) + p.ph.err <- name return } f, ok := file.(*File) @@ -173,8 +189,21 @@ func (ph *PreloadHandler) preloadStatus(ctx context.Context) { ph.mu.Unlock() case name := <-ph.err: ph.mu.Lock() - ph.q.Add(ph, name, -1) - ph.schedule() + p := ph.q.GetPreload(name) + if p != nil { + p.stop(false) + p.delay = time.Second * 2 + if p.Errc >= 10 { + if p.Prio >= 0 { + p.Prio = 0 + } + p.Prio -= 1 + ph.schedule() + } else { + p.Errc += 1 + go p.start() + } + } ph.mu.Unlock() } } diff --git a/pkg/srv/interceptor.go b/pkg/srv/interceptor.go index 4300de1..6b840c5 100644 --- a/pkg/srv/interceptor.go +++ b/pkg/srv/interceptor.go @@ -61,6 +61,7 @@ type file struct { Anchor string Status int Prio int + Errc int Running bool } @@ -138,6 +139,7 @@ func getPreloads(path string, fs *fs.FS) (dc dirContents) { URI: template.HTML(p.Name), Status: p.Status, Prio: p.Prio, + Errc: p.Errc, Running: p.Running, }) } diff --git a/pkg/srv/templates/head.html b/pkg/srv/templates/head.html index d1bc28e..9d2d333 100644 --- a/pkg/srv/templates/head.html +++ b/pkg/srv/templates/head.html @@ -94,6 +94,9 @@ td { .green { background-color: #4caf50; } +.status-red { + color: #e74c3c; +} .status-yellow { color: #f39c12; } diff --git a/pkg/srv/templates/preloads.html b/pkg/srv/templates/preloads.html index 63ab6c1..86e242e 100644 --- a/pkg/srv/templates/preloads.html +++ b/pkg/srv/templates/preloads.html @@ -14,7 +14,17 @@ Quota: {{.QuotaCur}} / {{.QuotaMax}} GiB