Add multi-disk copy workflow

This commit is contained in:
2026-04-23 22:24:32 +03:00
parent 5b3cb9e393
commit 31bac2b5d8
10 changed files with 468 additions and 204 deletions

View File

@@ -31,38 +31,46 @@ type Options struct {
type Copier struct {
tasks *task.Store
mu sync.Mutex
cancel context.CancelFunc
mu sync.Mutex
cancels map[string]context.CancelFunc
dbMu sync.RWMutex
db *db.DB
dbs map[string]*db.DB
}
func New(tasks *task.Store) *Copier {
return &Copier{tasks: tasks}
return &Copier{
tasks: tasks,
cancels: make(map[string]context.CancelFunc),
dbs: make(map[string]*db.DB),
}
}
func (c *Copier) SetDB(d *db.DB) {
func (c *Copier) SetDB(diskID string, d *db.DB) {
c.dbMu.Lock()
c.db = d
if d == nil {
delete(c.dbs, diskID)
} else {
c.dbs[diskID] = d
}
c.dbMu.Unlock()
}
func (c *Copier) getDB() *db.DB {
func (c *Copier) getDB(diskID string) *db.DB {
c.dbMu.RLock()
defer c.dbMu.RUnlock()
return c.db
return c.dbs[diskID]
}
func (c *Copier) Start(ctx context.Context, opts Options) (string, error) {
c.mu.Lock()
defer c.mu.Unlock()
if _, active := c.tasks.ActiveTask(); active {
if _, active := c.cancels[opts.DiskID]; active {
return "", errors.New("copy already running")
}
database := c.getDB()
database := c.getDB(opts.DiskID)
if database == nil {
return "", errors.New("no disk database available")
}
@@ -71,23 +79,29 @@ func (c *Copier) Start(ctx context.Context, opts Options) (string, error) {
opts.DestFolder = "media"
}
t := c.tasks.Create("copy")
t := c.tasks.Create("copy", opts.DiskID)
copyCtx, cancel := context.WithCancel(ctx)
c.cancel = cancel
c.cancels[opts.DiskID] = cancel
go c.run(copyCtx, t.ID, opts, database)
return t.ID, nil
}
func (c *Copier) Cancel() {
func (c *Copier) Cancel(diskID string) {
c.mu.Lock()
defer c.mu.Unlock()
if c.cancel != nil {
c.cancel()
if cancel, ok := c.cancels[diskID]; ok {
cancel()
}
}
func (c *Copier) run(ctx context.Context, taskID string, opts Options, database *db.DB) {
defer func() {
c.mu.Lock()
delete(c.cancels, opts.DiskID)
c.mu.Unlock()
}()
setStatus := func(s task.Status, msg string, prog int) {
c.tasks.Update(taskID, func(t *task.Task) {
t.Status = s