feat(16-03): WriteTrackTags pipeline with player safety, scan mutex, events, and app wiring
- TagWriter struct with WriteTrackTags entry point orchestrating full pipeline - PlayerStopper interface + playerAdapter for import-cycle-free player safety - PipelineLocker interface + pipelineMu on Library for scan/write mutual exclusion - TrackMetadataChanged event constant + auto-generated TypeScript events - TagWriter wired into app.go as Wails binding with SetContext in OnStartup - 5 pipeline integration tests: player safety, scan mutex, orphan cleanup, genre relink, full DB sync - Lint fixes: static error, else-if, wsl cuddle, golines
This commit is contained in:
@@ -110,6 +110,11 @@ type Library struct {
|
||||
// scanHooks holds callbacks for post-scan processing
|
||||
// (e.g. resolving phantom playlist tracks).
|
||||
scanHooks ScanHooks
|
||||
|
||||
// pipelineMu provides mutual exclusion between the scan
|
||||
// pipeline and the tag write pipeline. Acquired at the
|
||||
// start of each pipeline, released at the end.
|
||||
pipelineMu sync.Mutex
|
||||
}
|
||||
|
||||
// SetRescanHooks provides optional hooks for cross-cutting
|
||||
@@ -157,6 +162,15 @@ func NewLibrary(
|
||||
return library, nil
|
||||
}
|
||||
|
||||
// AcquirePipelineLock acquires the pipeline mutex for a tag write
|
||||
// operation. The caller must call ReleasePipelineLock when done.
|
||||
// If a scan is currently in progress, AcquirePipelineLock blocks
|
||||
// until it completes (and vice versa).
|
||||
func (l *Library) AcquirePipelineLock() { l.pipelineMu.Lock() }
|
||||
|
||||
// ReleasePipelineLock releases the pipeline mutex after a tag write.
|
||||
func (l *Library) ReleasePipelineLock() { l.pipelineMu.Unlock() }
|
||||
|
||||
// SetContext sets the Wails runtime context and registers event handlers.
|
||||
func (l *Library) SetContext(ctx context.Context) {
|
||||
l.mu.Lock()
|
||||
@@ -187,6 +201,10 @@ func (l *Library) scanInternal(
|
||||
libraryName string,
|
||||
libraryPath string,
|
||||
) *ScanMetrics {
|
||||
// Acquire pipeline lock for scan/write mutual exclusion.
|
||||
l.pipelineMu.Lock()
|
||||
defer l.pipelineMu.Unlock()
|
||||
|
||||
metrics := newScanMetrics()
|
||||
metrics.LibraryID = libraryID
|
||||
metrics.LibraryName = libraryName
|
||||
|
||||
Reference in New Issue
Block a user