Add multi-disk copy workflow
This commit is contained in:
@@ -34,59 +34,74 @@ func main() {
|
||||
taskStore := task.NewStore()
|
||||
cp := copier.New(taskStore)
|
||||
|
||||
var activeDB *db.DB
|
||||
var activeDiskID string
|
||||
activeDBs := make(map[string]*db.DB)
|
||||
mountToDiskID := make(map[string]string)
|
||||
|
||||
openDiskDB := func(info disk.DiskInfo) {
|
||||
if activeDiskID == info.DiskID {
|
||||
return // already open for this disk
|
||||
if info.DiskID == "" {
|
||||
return
|
||||
}
|
||||
if activeDB != nil {
|
||||
activeDB.Close()
|
||||
activeDB = nil
|
||||
activeDiskID = ""
|
||||
|
||||
if prevDiskID, ok := mountToDiskID[info.MountPath]; ok && prevDiskID != info.DiskID {
|
||||
if prevDB := activeDBs[prevDiskID]; prevDB != nil {
|
||||
prevDB.Close()
|
||||
delete(activeDBs, prevDiskID)
|
||||
cp.SetDB(prevDiskID, nil)
|
||||
}
|
||||
}
|
||||
mountToDiskID[info.MountPath] = info.DiskID
|
||||
|
||||
if _, ok := activeDBs[info.DiskID]; ok {
|
||||
return
|
||||
}
|
||||
|
||||
d, err := db.Open(disk.DBPath(info.MountPath))
|
||||
if err != nil {
|
||||
log.Printf("open disk DB: %v", err)
|
||||
return
|
||||
}
|
||||
activeDB = d
|
||||
activeDiskID = info.DiskID
|
||||
cp.SetDB(d)
|
||||
activeDBs[info.DiskID] = d
|
||||
cp.SetDB(info.DiskID, d)
|
||||
log.Printf("disk DB opened for %s", info.DiskID)
|
||||
}
|
||||
|
||||
closeDiskDB := func() {
|
||||
if activeDB != nil {
|
||||
activeDB.Close()
|
||||
activeDB = nil
|
||||
activeDiskID = ""
|
||||
cp.SetDB(nil)
|
||||
log.Println("disk DB closed")
|
||||
closeDiskDB := func(info disk.DiskInfo) {
|
||||
diskID := info.DiskID
|
||||
if diskID == "" {
|
||||
diskID = mountToDiskID[info.MountPath]
|
||||
}
|
||||
if diskID == "" {
|
||||
return
|
||||
}
|
||||
|
||||
cp.Cancel(diskID)
|
||||
cp.SetDB(diskID, nil)
|
||||
|
||||
if d := activeDBs[diskID]; d != nil {
|
||||
d.Close()
|
||||
delete(activeDBs, diskID)
|
||||
log.Printf("disk DB closed for %s", diskID)
|
||||
}
|
||||
delete(mountToDiskID, info.MountPath)
|
||||
}
|
||||
|
||||
watcherReady := false
|
||||
w := watcher.New(*mountPath, 5*time.Second, func(ev watcher.DiskEvent) {
|
||||
log.Printf("disk: %s -> %s", ev.Prev, ev.Info.State)
|
||||
log.Printf("disk: %s %s -> %s", ev.Info.MountPath, ev.Prev.State, ev.Info.State)
|
||||
switch ev.Info.State {
|
||||
case disk.DiskKnown:
|
||||
openDiskDB(ev.Info)
|
||||
if ev.Prev != disk.DiskKnown && cfg.AutoCopy {
|
||||
if watcherReady && ev.Prev.State != disk.DiskKnown && cfg.AutoCopy {
|
||||
triggerAutoCopy(cp, cfg, ev.Info, *mediaPath)
|
||||
}
|
||||
case disk.DiskForeign:
|
||||
closeDiskDB(ev.Prev)
|
||||
case disk.DiskAbsent:
|
||||
closeDiskDB()
|
||||
closeDiskDB(ev.Prev)
|
||||
}
|
||||
})
|
||||
|
||||
// Open DB immediately if disk already connected at startup
|
||||
{
|
||||
info, _ := disk.Probe(*mountPath)
|
||||
if info.State == disk.DiskKnown {
|
||||
openDiskDB(info)
|
||||
}
|
||||
}
|
||||
w.ProbeNow()
|
||||
watcherReady = true
|
||||
|
||||
srv, err := api.New(api.Deps{
|
||||
Config: cfg,
|
||||
@@ -96,6 +111,13 @@ func main() {
|
||||
Tasks: taskStore,
|
||||
MediaPath: *mediaPath,
|
||||
MountPath: *mountPath,
|
||||
OnDiskInit: func(mountPath, diskID string) {
|
||||
openDiskDB(disk.DiskInfo{
|
||||
State: disk.DiskKnown,
|
||||
DiskID: diskID,
|
||||
MountPath: mountPath,
|
||||
})
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("init server: %v", err)
|
||||
@@ -119,7 +141,9 @@ func main() {
|
||||
shutCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
httpSrv.Shutdown(shutCtx)
|
||||
closeDiskDB()
|
||||
for _, info := range w.ListDisks() {
|
||||
closeDiskDB(info)
|
||||
}
|
||||
}
|
||||
|
||||
func triggerAutoCopy(cp *copier.Copier, cfg *config.Config, info disk.DiskInfo, mediaPath string) {
|
||||
|
||||
Reference in New Issue
Block a user