Keep one draft in flight per week
A confirmed draft asked for while the week's draft job was asked for without confirm no longer enqueues a second job. With two job workers the two drafts ran at once, and whichever stored second failed plan_changed, so the household's confirmed draft could fail. StartDraft now refuses it with ErrDraftRunning, 409 draft_running, and enqueues nothing; the household asks again once the running draft finishes. Every other draft joins the week's queued or running job, so a week has at most one. The plan tests run the job runner with two workers, as cmd/server does, and a confirmed draft during a running unconfirmed one is refused while only the running job drafts. Maestro task ea48e650-d510-49cc-8485-0f07174ee731. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+17
-12
@@ -34,30 +34,35 @@ func (q *Queries) CreateWeekPlan(ctx context.Context, arg CreateWeekPlanParams)
|
||||
return err
|
||||
}
|
||||
|
||||
const getActiveDraftJobID = `-- name: GetActiveDraftJobID :one
|
||||
SELECT id FROM jobs
|
||||
const getActiveDraftJob = `-- name: GetActiveDraftJob :one
|
||||
SELECT id, CAST(json_extract(payload, '$.confirm') = 1 AS INTEGER) AS confirmed
|
||||
FROM jobs
|
||||
WHERE kind = ?1
|
||||
AND status IN ('queued', 'running')
|
||||
AND json_extract(payload, '$.week_start') = ?2
|
||||
AND (CAST(?3 AS INTEGER) = 0 OR json_extract(payload, '$.confirm') = 1)
|
||||
ORDER BY id
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
type GetActiveDraftJobIDParams struct {
|
||||
type GetActiveDraftJobParams struct {
|
||||
Kind string
|
||||
WeekStart string
|
||||
}
|
||||
|
||||
type GetActiveDraftJobRow struct {
|
||||
ID string
|
||||
Confirmed int64
|
||||
}
|
||||
|
||||
// The id of the job of kind queued or running for the week starting
|
||||
// week_start, one whose payload has confirm when confirmed is 1. Returns
|
||||
// sql.ErrNoRows when there is none.
|
||||
func (q *Queries) GetActiveDraftJobID(ctx context.Context, arg GetActiveDraftJobIDParams) (string, error) {
|
||||
row := q.db.QueryRowContext(ctx, getActiveDraftJobID, arg.Kind, arg.WeekStart, arg.Confirmed)
|
||||
var id string
|
||||
err := row.Scan(&id)
|
||||
return id, err
|
||||
// The job of kind queued or running for the week starting week_start,
|
||||
// with whether its payload has confirm. StartDraft enqueues a draft only
|
||||
// when there is none, so there is at most one. Returns sql.ErrNoRows when
|
||||
// there is none.
|
||||
func (q *Queries) GetActiveDraftJob(ctx context.Context, arg GetActiveDraftJobParams) (GetActiveDraftJobRow, error) {
|
||||
row := q.db.QueryRowContext(ctx, getActiveDraftJob, arg.Kind, arg.WeekStart)
|
||||
var i GetActiveDraftJobRow
|
||||
err := row.Scan(&i.ID, &i.Confirmed)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getWeekPlan = `-- name: GetWeekPlan :one
|
||||
|
||||
Reference in New Issue
Block a user