Files
SaveAny-Bot/database/task.go
T

93 lines
2.4 KiB
Go

package database
import (
"context"
"errors"
"time"
)
var errNotInitialized = errors.New("database not initialized")
type TaskStatus string
const (
TaskStatusQueued TaskStatus = "queued"
TaskStatusRunning TaskStatus = "running"
TaskStatusFailed TaskStatus = "failed"
TaskStatusCancelled TaskStatus = "cancelled"
)
// Task is the persisted record of a queued or running task, used to recover
// unfinished work after a process restart. Completed tasks are deleted on
// finish, so the table only ever holds queued/running rows.
type Task struct {
ID string `gorm:"primaryKey;size:64"`
Type string `gorm:"size:32;index"`
Payload []byte
Status string `gorm:"size:16;index"`
Error string
CreatedAt time.Time
UpdatedAt time.Time
}
func CreateTask(ctx context.Context, task *Task) error {
if db == nil {
return errNotInitialized
}
return db.WithContext(ctx).Create(task).Error
}
// UpsertTask inserts the task or replaces the existing row with the same ID.
func UpsertTask(ctx context.Context, task *Task) error {
if db == nil {
return errNotInitialized
}
return db.WithContext(ctx).Save(task).Error
}
func UpdateTaskStatus(ctx context.Context, id string, status TaskStatus, errMsg string) error {
if db == nil {
return errNotInitialized
}
return db.WithContext(ctx).Model(&Task{}).
Where("id = ?", id).
Updates(map[string]any{
"status": status,
"error": errMsg,
"updated_at": time.Now(),
}).Error
}
func DeleteTask(ctx context.Context, id string) error {
if db == nil {
return errNotInitialized
}
return db.WithContext(ctx).Delete(&Task{}, "id = ?", id).Error
}
// GetUnfinishedTasks returns all tasks that were not finished when the
// process stopped, i.e. tasks that must be re-enqueued on startup.
func GetUnfinishedTasks(ctx context.Context) ([]Task, error) {
if db == nil {
return nil, errNotInitialized
}
var tasks []Task
err := db.WithContext(ctx).
Where("status IN ?", []string{string(TaskStatusQueued), string(TaskStatusRunning)}).
Order("created_at").
Find(&tasks).Error
return tasks, err
}
func CountUnfinishedTasks(ctx context.Context) (int64, error) {
if db == nil {
return 0, errNotInitialized
}
var count int64
err := db.WithContext(ctx).
Model(&Task{}).
Where("status IN ?", []string{string(TaskStatusQueued), string(TaskStatusRunning)}).
Count(&count).Error
return count, err
}