Add multi-disk copy workflow
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user