8c0fbc8ffa
Postgres rejects FOR UPDATE on the nullable side of a LEFT JOIN, which made LeaseNextQueuedDesktopTask fail under contention. Replace the join with a NOT EXISTS subquery, scope the row lock to the dt alias, and add a regression test plus warn-level logging on lease query failures so similar issues are easier to diagnose.
230 lines
5.8 KiB
SQL
230 lines
5.8 KiB
SQL
-- name: CreateDesktopPublishJob :one
|
|
INSERT INTO desktop_publish_jobs (
|
|
desktop_id,
|
|
tenant_id,
|
|
workspace_id,
|
|
created_by_user_id,
|
|
title,
|
|
content_ref,
|
|
scheduled_at,
|
|
article_id,
|
|
article_version_id
|
|
)
|
|
VALUES (
|
|
sqlc.arg(desktop_id),
|
|
sqlc.arg(tenant_id),
|
|
sqlc.arg(workspace_id),
|
|
sqlc.arg(created_by_user_id),
|
|
sqlc.arg(title),
|
|
sqlc.arg(content_ref),
|
|
sqlc.narg(scheduled_at),
|
|
sqlc.narg(article_id),
|
|
sqlc.narg(article_version_id)
|
|
)
|
|
RETURNING *;
|
|
|
|
-- name: CreateDesktopTask :one
|
|
INSERT INTO desktop_tasks (
|
|
desktop_id,
|
|
job_id,
|
|
tenant_id,
|
|
workspace_id,
|
|
target_account_id,
|
|
target_client_id,
|
|
platform_id,
|
|
kind,
|
|
payload,
|
|
status,
|
|
dedup_key
|
|
)
|
|
VALUES (
|
|
sqlc.arg(desktop_id),
|
|
sqlc.arg(job_id),
|
|
sqlc.arg(tenant_id),
|
|
sqlc.arg(workspace_id),
|
|
sqlc.arg(target_account_id),
|
|
sqlc.arg(target_client_id),
|
|
sqlc.arg(platform_id),
|
|
sqlc.arg(kind),
|
|
sqlc.arg(payload),
|
|
sqlc.arg(status),
|
|
sqlc.narg(dedup_key)
|
|
)
|
|
RETURNING *;
|
|
|
|
-- name: GetDesktopTaskByDesktopID :one
|
|
SELECT *
|
|
FROM desktop_tasks
|
|
WHERE desktop_id = sqlc.arg(desktop_id)
|
|
AND workspace_id = sqlc.arg(workspace_id)
|
|
LIMIT 1;
|
|
|
|
-- name: LeaseNextQueuedDesktopTask :one
|
|
WITH candidate AS (
|
|
SELECT dt.desktop_id
|
|
FROM desktop_tasks AS dt
|
|
WHERE dt.target_client_id = sqlc.arg(client_id)
|
|
AND dt.status = 'queued'
|
|
AND (
|
|
sqlc.narg(kind)::text IS NULL
|
|
OR dt.kind = sqlc.narg(kind)::text
|
|
)
|
|
AND (
|
|
dt.kind <> 'publish'
|
|
OR NOT EXISTS (
|
|
SELECT 1
|
|
FROM desktop_publish_jobs AS j
|
|
WHERE j.desktop_id = dt.job_id
|
|
AND j.status <> 'queued'
|
|
)
|
|
)
|
|
ORDER BY dt.lane_weight DESC,
|
|
dt.priority DESC,
|
|
COALESCE(dt.enqueued_at, dt.created_at) ASC,
|
|
dt.created_at ASC,
|
|
dt.desktop_id ASC
|
|
LIMIT 1
|
|
FOR UPDATE OF dt SKIP LOCKED
|
|
)
|
|
UPDATE desktop_tasks AS t
|
|
SET active_attempt_id = sqlc.arg(attempt_id),
|
|
lease_token_hash = sqlc.arg(lease_token_hash),
|
|
lease_expires_at = now() + interval '10 minutes',
|
|
status = 'in_progress',
|
|
attempts = t.attempts + 1,
|
|
updated_at = now()
|
|
FROM candidate
|
|
WHERE t.desktop_id = candidate.desktop_id
|
|
RETURNING t.*;
|
|
|
|
-- name: LeaseQueuedDesktopTaskByDesktopID :one
|
|
UPDATE desktop_tasks
|
|
SET active_attempt_id = sqlc.arg(attempt_id),
|
|
lease_token_hash = sqlc.arg(lease_token_hash),
|
|
lease_expires_at = now() + interval '10 minutes',
|
|
status = 'in_progress',
|
|
attempts = attempts + 1,
|
|
updated_at = now()
|
|
WHERE desktop_id = sqlc.arg(desktop_id)
|
|
AND target_client_id = sqlc.arg(client_id)
|
|
AND status = 'queued'
|
|
RETURNING *;
|
|
|
|
-- name: ExtendDesktopTaskLease :one
|
|
UPDATE desktop_tasks
|
|
SET lease_expires_at = now() + interval '10 minutes',
|
|
updated_at = now()
|
|
WHERE desktop_id = sqlc.arg(desktop_id)
|
|
AND lease_token_hash = sqlc.arg(lease_token_hash)
|
|
AND status = 'in_progress'
|
|
RETURNING *;
|
|
|
|
-- name: CompleteDesktopTask :one
|
|
UPDATE desktop_tasks
|
|
SET status = sqlc.arg(status),
|
|
result = sqlc.narg(result),
|
|
error = sqlc.narg(error),
|
|
active_attempt_id = NULL,
|
|
lease_token_hash = NULL,
|
|
lease_expires_at = NULL,
|
|
updated_at = now()
|
|
WHERE desktop_id = sqlc.arg(desktop_id)
|
|
AND lease_token_hash = sqlc.arg(lease_token_hash)
|
|
AND status = 'in_progress'
|
|
RETURNING *;
|
|
|
|
-- name: CancelDesktopTaskByLease :one
|
|
UPDATE desktop_tasks
|
|
SET status = 'aborted',
|
|
error = sqlc.narg(error),
|
|
active_attempt_id = NULL,
|
|
lease_token_hash = NULL,
|
|
lease_expires_at = NULL,
|
|
updated_at = now()
|
|
WHERE desktop_id = sqlc.arg(desktop_id)
|
|
AND lease_token_hash = sqlc.arg(lease_token_hash)
|
|
AND status = 'in_progress'
|
|
RETURNING *;
|
|
|
|
-- name: CancelDesktopTaskByClient :one
|
|
UPDATE desktop_tasks
|
|
SET status = 'aborted',
|
|
error = sqlc.narg(error),
|
|
active_attempt_id = NULL,
|
|
lease_token_hash = NULL,
|
|
lease_expires_at = NULL,
|
|
updated_at = now()
|
|
WHERE desktop_id = sqlc.arg(desktop_id)
|
|
AND target_client_id = sqlc.arg(client_id)
|
|
AND status = 'queued'
|
|
RETURNING *;
|
|
|
|
-- name: TenantCancelDesktopTask :one
|
|
UPDATE desktop_tasks
|
|
SET status = 'aborted',
|
|
error = sqlc.narg(error),
|
|
active_attempt_id = NULL,
|
|
lease_token_hash = NULL,
|
|
lease_expires_at = NULL,
|
|
updated_at = now()
|
|
WHERE desktop_id = sqlc.arg(desktop_id)
|
|
AND workspace_id = sqlc.arg(workspace_id)
|
|
AND status = 'queued'
|
|
RETURNING *;
|
|
|
|
-- name: ReconcileDesktopTask :one
|
|
UPDATE desktop_tasks
|
|
SET status = CASE
|
|
WHEN sqlc.arg(status)::text = 'retry' THEN 'queued'
|
|
ELSE sqlc.arg(status)::text
|
|
END,
|
|
result = CASE
|
|
WHEN sqlc.arg(status)::text = 'retry' THEN NULL
|
|
ELSE sqlc.narg(result)
|
|
END,
|
|
error = sqlc.narg(error),
|
|
active_attempt_id = NULL,
|
|
lease_token_hash = NULL,
|
|
lease_expires_at = NULL,
|
|
attempts = attempts + CASE WHEN sqlc.arg(status)::text = 'retry' THEN 1 ELSE 0 END,
|
|
updated_at = now()
|
|
WHERE desktop_id = sqlc.arg(desktop_id)
|
|
AND workspace_id = sqlc.arg(workspace_id)
|
|
AND status = 'unknown'
|
|
RETURNING *;
|
|
|
|
-- name: MarkDesktopTasksUnknownByClient :execrows
|
|
UPDATE desktop_tasks
|
|
SET status = 'unknown',
|
|
error = sqlc.narg(error),
|
|
active_attempt_id = NULL,
|
|
lease_token_hash = NULL,
|
|
lease_expires_at = NULL,
|
|
updated_at = now()
|
|
WHERE target_client_id = sqlc.arg(client_id)
|
|
AND workspace_id = sqlc.arg(workspace_id)
|
|
AND status = 'in_progress';
|
|
|
|
-- name: CreateDesktopTaskAttempt :one
|
|
INSERT INTO desktop_task_attempts (
|
|
desktop_id,
|
|
task_id,
|
|
client_id,
|
|
lease_token_hash
|
|
)
|
|
VALUES (
|
|
sqlc.arg(desktop_id),
|
|
sqlc.arg(task_id),
|
|
sqlc.arg(client_id),
|
|
sqlc.arg(lease_token_hash)
|
|
)
|
|
RETURNING *;
|
|
|
|
-- name: FinishDesktopTaskAttempt :exec
|
|
UPDATE desktop_task_attempts
|
|
SET ended_at = now(),
|
|
final_status = sqlc.narg(final_status),
|
|
error = sqlc.narg(error)
|
|
WHERE task_id = sqlc.arg(task_id)
|
|
AND desktop_id = sqlc.arg(attempt_id);
|