package flash import ( "sync" "visiona-local/server/internal/driver" ) type FlashTask struct { ID string DeviceID string ModelID string ProgressCh chan driver.FlashProgress Done bool } type ProgressTracker struct { tasks map[string]*FlashTask mu sync.Mutex } func NewProgressTracker() *ProgressTracker { return &ProgressTracker{ tasks: make(map[string]*FlashTask), } } // Create 建立新 flash task。如果同 taskID 已存在且未完成,回傳 nil 表示拒絕。 func (pt *ProgressTracker) Create(taskID, deviceID, modelID string) *FlashTask { pt.mu.Lock() defer pt.mu.Unlock() // M3 fix: 防止同裝置重複 flash — 舊 task 未完成就拒絕 if existing, ok := pt.tasks[taskID]; ok && !existing.Done { return nil } task := &FlashTask{ ID: taskID, DeviceID: deviceID, ModelID: modelID, ProgressCh: make(chan driver.FlashProgress, 20), Done: false, } pt.tasks[taskID] = task return task } func (pt *ProgressTracker) Get(taskID string) (*FlashTask, bool) { pt.mu.Lock() defer pt.mu.Unlock() t, ok := pt.tasks[taskID] return t, ok } // Remove 清除已完成的 task,釋放 map entry。 func (pt *ProgressTracker) Remove(taskID string) { pt.mu.Lock() defer pt.mu.Unlock() delete(pt.tasks, taskID) }