Files
ddc/internal/jobs/job.go
T

126 lines
2.7 KiB
Go
Executable File

package jobs
import (
"context"
"slices"
"sync"
"sync/atomic"
"time"
"ddc/internal/fetch"
)
type Status string
const (
StatusQueued Status = "queued"
StatusDownloading Status = "downloading"
StatusPaused Status = "paused"
StatusExtracting Status = "extracting"
StatusReady Status = "ready"
StatusMoving Status = "moving"
StatusCompleted Status = "completed"
StatusFailed Status = "failed"
StatusCancelled Status = "cancelled"
)
type Snapshot struct {
ID string `json:"id"`
SourceURL string `json:"sourceUrl"`
FileName string `json:"fileName"`
Status Status `json:"status"`
Message string `json:"message"`
BytesDone int64 `json:"bytesDone"`
BytesTotal int64 `json:"bytesTotal"`
CreatedAt time.Time `json:"createdAt"`
MoveTarget string `json:"moveTarget,omitempty"`
QueuePosition int `json:"queuePosition,omitempty"`
}
type Job struct {
id string
sourceURL string
displayURL string
directory string
requestedName string
autoExtract bool
target *moveTarget
createdAt time.Time
jobContext context.Context
cancel context.CancelFunc
workers sync.WaitGroup
mutex sync.Mutex
status Status
message string
fileName string
deleted bool
downloaded bool
downloadState *fetch.State
cancelRun context.CancelCauseFunc
recordMutex sync.Mutex
bytesDone atomic.Int64
bytesTotal atomic.Int64
}
func (job *Job) setStatus(status Status, message string) {
job.mutex.Lock()
defer job.mutex.Unlock()
if job.deleted {
return
}
job.status = status
job.message = message
}
func (job *Job) currentStatus() Status {
job.mutex.Lock()
defer job.mutex.Unlock()
return job.status
}
func (job *Job) begin(to Status, allowedFrom ...Status) bool {
job.mutex.Lock()
defer job.mutex.Unlock()
if job.deleted || !slices.Contains(allowedFrom, job.status) {
return false
}
job.status = to
job.message = ""
job.workers.Add(1)
return true
}
func (job *Job) markDeleted() bool {
job.mutex.Lock()
defer job.mutex.Unlock()
if job.status == StatusMoving {
return false
}
job.deleted = true
job.status = StatusCancelled
return true
}
func (job *Job) snapshot() Snapshot {
job.mutex.Lock()
defer job.mutex.Unlock()
moveTargetPath := ""
if job.target != nil {
moveTargetPath = job.target.displayPath()
}
return Snapshot{
ID: job.id,
SourceURL: job.displayURL,
FileName: job.fileName,
Status: job.status,
Message: job.message,
BytesDone: job.bytesDone.Load(),
BytesTotal: job.bytesTotal.Load(),
CreatedAt: job.createdAt,
MoveTarget: moveTargetPath,
}
}