summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/service/admin.go16
-rw-r--r--internal/service/admin_test.go12
2 files changed, 22 insertions, 6 deletions
diff --git a/internal/service/admin.go b/internal/service/admin.go
index a775bed..673bf37 100644
--- a/internal/service/admin.go
+++ b/internal/service/admin.go
@@ -3,6 +3,7 @@ package service
import (
"context"
"fmt"
+ "time"
"codeberg.org/snonux/player/internal/auth"
"codeberg.org/snonux/player/internal/clock"
@@ -39,10 +40,17 @@ func (s *adminService) TriggerRescan(ctx context.Context) error {
if s.scanner == nil {
return fmt.Errorf("scanner not configured")
}
- // Use a background context so the scan isn't canceled when the HTTP request finishes.
- if err := s.scanner.Scan(context.Background(), s.mediaRoot); err != nil {
- return fmt.Errorf("scan failed: %w", err)
- }
+ // Run the scan in a background goroutine so the HTTP request
+ // returns immediately and the scan continues asynchronously.
+ go func() {
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute)
+ defer cancel()
+ if err := s.scanner.Scan(ctx, s.mediaRoot); err != nil {
+ fmt.Printf("[rescan] scan failed: %v\n", err)
+ } else {
+ fmt.Printf("[rescan] scan completed\n")
+ }
+ }()
return nil
}
diff --git a/internal/service/admin_test.go b/internal/service/admin_test.go
index bef8ca2..ac73ce2 100644
--- a/internal/service/admin_test.go
+++ b/internal/service/admin_test.go
@@ -57,9 +57,11 @@ func TestAdminService_ListTrash(t *testing.T) {
func TestAdminService_TriggerRescan(t *testing.T) {
ctx := context.Background()
var scannedRoot string
+ done := make(chan struct{})
sc := &fakeScanner{
scanFunc: func(_ context.Context, root string) error {
scannedRoot = root
+ close(done)
return nil
},
}
@@ -67,6 +69,8 @@ func TestAdminService_TriggerRescan(t *testing.T) {
if err := svc.TriggerRescan(ctx); err != nil {
t.Fatalf("unexpected error: %v", err)
}
+ <-done
+ // Give the background goroutine a moment to write scannedRoot.
if scannedRoot != "/media" {
t.Fatalf("expected root %q, got %q", "/media", scannedRoot)
}
@@ -74,16 +78,20 @@ func TestAdminService_TriggerRescan(t *testing.T) {
func TestAdminService_TriggerRescan_Error(t *testing.T) {
ctx := context.Background()
+ done := make(chan struct{})
sc := &fakeScanner{
scanFunc: func(_ context.Context, _ string) error {
+ close(done)
return errors.New("scan failed")
},
}
svc := NewAdminService(&repository.MockStore{}, newMockClock(), &fakeHasher{fixed: "hash"}, sc, "/media")
err := svc.TriggerRescan(ctx)
- if err == nil {
- t.Fatal("expected error")
+ // TriggerRescan now always returns nil immediately; failure is logged in background.
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
}
+ <-done
}
func TestAdminService_TriggerRescan_NilScanner(t *testing.T) {