Stream beets imports over HTTP.

feat(server): reject overlapping imports for active paths with 409 #27

Merged glerp.sullen.net
targeting main from glerp.sullen.net/goosefoot:feat/active-import-path-guard
Merged opened by and assigned to glerp.sullen.net
targeting main from glerp.sullen.net/goosefoot:feat/active-import-path-guard

Summary #

Reject concurrent POST /import requests targeting a canonical path that already has an active or queued dry_run: false import — or an overlapping ancestor/descendant path — with 409 Conflict before opening an SSE stream.

Changes #

  • Active-path tracking & ancestor/descendant overlap (internal/server/server.go, internal/server/import.go):
    • Track admitted dry_run: false canonical import paths in Server.activePaths under activePathsMutex, releasing each path and pending slot on pipeline completion or failure.
    • Check path equality and strict ancestor/descendant overlap (pathsOverlap) during admission in admitImportRequest prior to 429 Too Many Requests slot acquisition so 409 Conflict takes precedence over queue saturation without leaking slots.
    • Reject dry_run: true previews against active or queued dry_run: false paths with 409 Conflict while leaving dry_run: true paths out of activePaths, preserving concurrent candidate previews on idle paths and immediate dry_run: false imports while a preview is in flight.
  • Tests (internal/server/import_test.go, internal/server/server_test.go):
    • Behavioral tests covering exact and symlink-aliased duplicate paths (including 409 precedence when MaxPendingImports is full), ancestor/descendant vs. sibling-prefix paths, dry_run overlap rules, and path release after failed or completed imports.
Commits 0