Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
63 lines
2.1 KiB
Go
63 lines
2.1 KiB
Go
package jobs
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// Queue enqueues processing and feed-sync work for the worker poller (SKIP LOCKED claim).
|
|
// ASSUMPTION: full River client + river migrations are deferred; Postgres pending
|
|
// jobs + FOR UPDATE SKIP LOCKED is the production queue for P0-4 MVP.
|
|
type Queue struct {
|
|
Pool *pgxpool.Pool
|
|
}
|
|
|
|
func NewQueue(pool *pgxpool.Pool) *Queue {
|
|
return &Queue{Pool: pool}
|
|
}
|
|
|
|
// EnqueueProcessingJob ensures the job is pending and wakes listeners via NOTIFY.
|
|
func (q *Queue) EnqueueProcessingJob(ctx context.Context, jobID uuid.UUID) error {
|
|
if q == nil || q.Pool == nil {
|
|
return fmt.Errorf("jobs queue not configured")
|
|
}
|
|
ct, err := q.Pool.Exec(ctx, `
|
|
UPDATE processing_jobs
|
|
SET status = 'pending', updated_at = now(),
|
|
error = CASE WHEN status = 'failed' THEN NULL ELSE error END
|
|
WHERE id = $1 AND status IN ('pending', 'failed')`, jobID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if ct.RowsAffected() == 0 {
|
|
// Already running/completed/cancelled — still notify in case worker is idle.
|
|
var status string
|
|
_ = q.Pool.QueryRow(ctx, `SELECT status FROM processing_jobs WHERE id = $1`, jobID).Scan(&status)
|
|
log.Printf("jobs: enqueue %s status=%s (no status change)", jobID, status)
|
|
}
|
|
_, _ = q.Pool.Exec(ctx, `SELECT pg_notify('processing_jobs', $1)`, jobID.String())
|
|
return nil
|
|
}
|
|
|
|
// EnqueueFeedSyncJob wakes listeners for an already-pending feed_sync_jobs row.
|
|
// Row creation + mapping gates live in feeds.EnqueueSync; this mirrors processing NOTIFY.
|
|
func (q *Queue) EnqueueFeedSyncJob(ctx context.Context, jobID uuid.UUID) error {
|
|
if q == nil || q.Pool == nil {
|
|
return fmt.Errorf("jobs queue not configured")
|
|
}
|
|
var status string
|
|
err := q.Pool.QueryRow(ctx, `SELECT status FROM feed_sync_jobs WHERE id = $1`, jobID).Scan(&status)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if status != "pending" && status != "running" {
|
|
log.Printf("jobs: feed sync enqueue %s status=%s (notify only)", jobID, status)
|
|
}
|
|
_, _ = q.Pool.Exec(ctx, `SELECT pg_notify('feed_sync_jobs', $1)`, jobID.String())
|
|
return nil
|
|
}
|