Changeset 0.32.0 (#206)
This commit is contained in:
@@ -2,11 +2,12 @@ package sqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"git.gobha.me/xcaliber/chat-switchboard/models"
|
||||
"git.gobha.me/xcaliber/chat-switchboard/store"
|
||||
"chat-switchboard/models"
|
||||
"chat-switchboard/store"
|
||||
)
|
||||
|
||||
type TaskStore struct{}
|
||||
@@ -159,8 +160,20 @@ func (s *TaskStore) ListAll(ctx context.Context) ([]models.Task, error) {
|
||||
return s.list(ctx, `ORDER BY created_at DESC`)
|
||||
}
|
||||
|
||||
func (s *TaskStore) ListDue(ctx context.Context, limit int) ([]models.Task, error) {
|
||||
return s.list(ctx, `WHERE is_active = 1 AND next_run_at <= datetime('now') ORDER BY next_run_at ASC LIMIT ?`, limit)
|
||||
func (s *TaskStore) ClaimDueTask(ctx context.Context) (*models.Task, error) {
|
||||
// SQLite: single-process, no contention. Select the oldest due task,
|
||||
// then atomically clear next_run_at to mark it claimed.
|
||||
t := &models.Task{}
|
||||
row := DB.QueryRowContext(ctx,
|
||||
`SELECT `+taskColumns+` FROM tasks
|
||||
WHERE is_active = 1 AND next_run_at <= datetime('now')
|
||||
ORDER BY next_run_at ASC LIMIT 1`)
|
||||
if err := scanTask(row, t); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, _ = DB.ExecContext(ctx,
|
||||
`UPDATE tasks SET next_run_at = NULL WHERE id = ?`, t.ID)
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// ── Scheduler bookkeeping ──────────────────────
|
||||
@@ -194,6 +207,34 @@ func (s *TaskStore) CreateRun(ctx context.Context, r *models.TaskRun) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *TaskStore) CreateRunExclusive(ctx context.Context, taskID string) (*models.TaskRun, error) {
|
||||
// SQLite: check-then-insert. Single-process, no race.
|
||||
var count int
|
||||
err := DB.QueryRowContext(ctx, `
|
||||
SELECT COUNT(*) FROM task_runs
|
||||
WHERE task_id = ? AND status IN ('running', 'queued')`, taskID).Scan(&count)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count > 0 {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
r := &models.TaskRun{
|
||||
ID: store.NewID(),
|
||||
TaskID: taskID,
|
||||
Status: "running",
|
||||
StartedAt: time.Now().UTC(),
|
||||
}
|
||||
_, err = DB.ExecContext(ctx, `
|
||||
INSERT INTO task_runs (id, task_id, status, started_at)
|
||||
VALUES (?, ?, 'running', ?)`,
|
||||
r.ID, taskID, r.StartedAt.UTC().Format("2006-01-02 15:04:05"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (s *TaskStore) UpdateRun(ctx context.Context, id, status string, tokensUsed, toolCalls, wallClock int, errMsg string) error {
|
||||
_, err := DB.ExecContext(ctx, `
|
||||
UPDATE task_runs SET status = ?, tokens_used = ?, tool_calls = ?,
|
||||
|
||||
Reference in New Issue
Block a user