Go web application for filling USB drives with media files. Runs in Docker on Unraid with /media, /mnt/usb, /config volumes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
71 lines
1.1 KiB
Go
71 lines
1.1 KiB
Go
package watcher
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
|
|
"jukebox_maker/internal/disk"
|
|
)
|
|
|
|
type DiskEvent struct {
|
|
Info disk.DiskInfo
|
|
Prev disk.DiskState
|
|
}
|
|
|
|
type Handler func(event DiskEvent)
|
|
|
|
type Watcher struct {
|
|
mountPath string
|
|
interval time.Duration
|
|
handler Handler
|
|
|
|
mu sync.RWMutex
|
|
current disk.DiskInfo
|
|
}
|
|
|
|
func New(mountPath string, interval time.Duration, handler Handler) *Watcher {
|
|
return &Watcher{
|
|
mountPath: mountPath,
|
|
interval: interval,
|
|
handler: handler,
|
|
}
|
|
}
|
|
|
|
func (w *Watcher) CurrentDisk() disk.DiskInfo {
|
|
w.mu.RLock()
|
|
defer w.mu.RUnlock()
|
|
return w.current
|
|
}
|
|
|
|
func (w *Watcher) Run(ctx context.Context) {
|
|
ticker := time.NewTicker(w.interval)
|
|
defer ticker.Stop()
|
|
|
|
// probe immediately on start
|
|
w.probe()
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
w.probe()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (w *Watcher) probe() {
|
|
info, _ := disk.Probe(w.mountPath)
|
|
|
|
w.mu.Lock()
|
|
prev := w.current.State
|
|
changed := prev != info.State
|
|
w.current = info
|
|
w.mu.Unlock()
|
|
|
|
if changed && w.handler != nil {
|
|
w.handler(DiskEvent{Info: info, Prev: prev})
|
|
}
|
|
}
|