mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-06 21:36:37 +08:00
perf(strm): 优化 OpenList 元数据下载速度 (#15)
* Add favourite buttons to library list and series detail pages Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Fix favourites list for remote Emby mounted media Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Route favourites to library series detail when appropriate Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Fix favourites link to library series for remote anime paths Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Fix remote Emby playback history and continue watching - Preserve duration_ms when web player reports duration=0 - Add GET /playback/:id/resume for reliable per-item resume - Switch home continue watching to /watch-history/continue API - Set library_id on remote media for play-profile visibility - Keep continue-watching rows when remote metadata hydration fails Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Fix mobile sort dropdown overflowing off-screen Align dropdown to button left edge on small screens and cap width to viewport so sort options stay fully visible on mobile. Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Remove stale Windows binary backup files Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Fix STRM account edit form not echoing saved config Return config_preview from account API for server/url/username and secret flags. Merge partial config updates so empty password/token fields do not wipe stored credentials. Co-authored-by: truewhile <truewhile@users.noreply.github.com> * perf(strm): speed up OpenList metadata downloads with provider-aware concurrency - Split download semaphore: 115 stays capped at 3 for WAF safety; OpenList/CloudDrive2 WebDAV metadata uses strm.download_threads (default raised to 6, max 16) - Scope 115 WAF cooldown to 115 tasks only so OpenList downloads are not paused - Requeue claimed tasks back to pending when slot acquisition fails or 115 is cooling - Add tests for separate semaphores and requeue behavior Co-authored-by: truewhile <truewhile@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: truewhile <truewhile@users.noreply.github.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ShukeBta/MMTL/internal/model"
|
||||
"github.com/ShukeBta/MMTL/internal/repository"
|
||||
@@ -104,3 +105,62 @@ func TestStrmUploadTasksClearAndRetry(t *testing.T) {
|
||||
t.Fatalf("expected 2 remaining tasks, got %d", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDownloadSemSeparateByProvider(t *testing.T) {
|
||||
svc := NewStrmService(nil, zap.NewNop(), nil, nil)
|
||||
svc.initDownloadSems(6)
|
||||
|
||||
if cap(svc.downloadSem115) != strm115DownloadSemCap {
|
||||
t.Fatalf("115 sem cap = %d, want %d", cap(svc.downloadSem115), strm115DownloadSemCap)
|
||||
}
|
||||
if cap(svc.downloadSemDAV) != 6 {
|
||||
t.Fatalf("dav sem cap = %d, want 6", cap(svc.downloadSemDAV))
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
for i := 0; i < strm115DownloadSemCap; i++ {
|
||||
if !svc.acquireDownloadSlot(ctx, model.StrmProvider115) {
|
||||
t.Fatalf("failed to acquire 115 slot %d", i)
|
||||
}
|
||||
}
|
||||
// 115 槽位占满后,OpenList 仍应能独立获取槽位。
|
||||
if !svc.acquireDownloadSlot(ctx, model.StrmProviderOpenList) {
|
||||
t.Fatal("openlist slot should remain available while 115 slots are full")
|
||||
}
|
||||
for i := 0; i < 5; i++ {
|
||||
if !svc.acquireDownloadSlot(ctx, model.StrmProviderOpenList) {
|
||||
t.Fatalf("failed to acquire extra openlist slot %d", i)
|
||||
}
|
||||
}
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, 50*time.Millisecond)
|
||||
defer cancel()
|
||||
if svc.acquireDownloadSlot(timeoutCtx, model.StrmProviderOpenList) {
|
||||
t.Fatal("expected openlist slots to be exhausted after 6 acquisitions")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequeueDownloadTask(t *testing.T) {
|
||||
db := newServiceTestDB(t, &model.StrmDownloadTask{})
|
||||
repos := repository.New(db)
|
||||
svc := NewStrmService(nil, zap.NewNop(), repos, nil)
|
||||
now := time.Now()
|
||||
task := &model.StrmDownloadTask{
|
||||
Base: model.Base{ID: "dl-running"},
|
||||
Status: model.StrmTaskRunning,
|
||||
Provider: model.StrmProviderOpenList,
|
||||
StartedAt: &now,
|
||||
}
|
||||
if err := db.Create(task).Error; err != nil {
|
||||
t.Fatalf("insert task: %v", err)
|
||||
}
|
||||
|
||||
svc.requeueDownloadTask(task)
|
||||
|
||||
var got model.StrmDownloadTask
|
||||
if err := db.First(&got, "id = ?", task.ID).Error; err != nil {
|
||||
t.Fatalf("load task: %v", err)
|
||||
}
|
||||
if got.Status != model.StrmTaskPending || got.StartedAt != nil {
|
||||
t.Fatalf("task not requeued: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user