Files
jukebox_maker/internal/task/task.go
Michael Chus 29f3ad9576 Add jukebox_maker web app v1.0
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>
2026-04-23 21:33:43 +03:00

89 lines
1.7 KiB
Go

package task
import (
"sync"
"time"
"github.com/google/uuid"
)
type Status string
const (
StatusQueued Status = "queued"
StatusRunning Status = "running"
StatusSuccess Status = "success"
StatusFailed Status = "failed"
StatusCanceled Status = "canceled"
)
type Task struct {
ID string `json:"id"`
Type string `json:"type"`
Status Status `json:"status"`
Progress int `json:"progress"`
Message string `json:"message"`
Error string `json:"error"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func (t *Task) IsTerminal() bool {
return t.Status == StatusSuccess || t.Status == StatusFailed || t.Status == StatusCanceled
}
type Store struct {
mu sync.RWMutex
tasks map[string]*Task
}
func NewStore() *Store {
return &Store{tasks: make(map[string]*Task)}
}
func (s *Store) Create(taskType string) *Task {
t := &Task{
ID: uuid.New().String(),
Type: taskType,
Status: StatusQueued,
CreatedAt: time.Now().UTC(),
UpdatedAt: time.Now().UTC(),
}
s.mu.Lock()
s.tasks[t.ID] = t
s.mu.Unlock()
return t
}
func (s *Store) Get(id string) (*Task, bool) {
s.mu.RLock()
defer s.mu.RUnlock()
t, ok := s.tasks[id]
if !ok {
return nil, false
}
copy := *t
return &copy, true
}
func (s *Store) Update(id string, fn func(*Task)) {
s.mu.Lock()
defer s.mu.Unlock()
if t, ok := s.tasks[id]; ok {
fn(t)
t.UpdatedAt = time.Now().UTC()
}
}
func (s *Store) ActiveTask() (*Task, bool) {
s.mu.RLock()
defer s.mu.RUnlock()
for _, t := range s.tasks {
if t.Status == StatusQueued || t.Status == StatusRunning {
copy := *t
return &copy, true
}
}
return nil, false
}