Revert "web designer: Queue engine test"
This reverts commit d4ee3ff960.
This commit is contained in:
parent
d4ee3ff960
commit
ad0892a539
6 changed files with 0 additions and 154 deletions
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Mark a Web Designer task terminal. Used by the console runner after it runs
|
||||
* the design agent + build + commit (or on failure).
|
||||
*
|
||||
* php api/cli/tasks-finish.php --id=42 --status=published --result='{"commit":"abc123","summary":"...","live":"/about"}'
|
||||
* php api/cli/tasks-finish.php --id=42 --status=failed --result='{"error":"build failed"}'
|
||||
*
|
||||
* status must be one of: published, failed. `result` is stored verbatim as JSON.
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
require __DIR__ . '/../config.php';
|
||||
|
||||
$opts = getopt('', ['id:', 'status:', 'result::']);
|
||||
$id = (int) ($opts['id'] ?? 0);
|
||||
$status = (string) ($opts['status'] ?? '');
|
||||
$result = (string) ($opts['result'] ?? '{}');
|
||||
|
||||
if ($id <= 0 || !in_array($status, ['published', 'failed'], true)) {
|
||||
fwrite(STDERR, "usage: tasks-finish.php --id=<n> --status=published|failed --result=<json>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Validate the result payload is JSON; fall back to empty object if not.
|
||||
if (json_decode($result) === null && json_last_error() !== JSON_ERROR_NONE) {
|
||||
$result = '{}';
|
||||
}
|
||||
|
||||
$pdo = new PDO(
|
||||
sprintf('mysql:host=%s;dbname=%s;charset=utf8mb4', DB_HOST, DB_NAME),
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
|
||||
);
|
||||
|
||||
$stmt = $pdo->prepare(
|
||||
'UPDATE cja_tasks SET status = ?, result = ?, finished_at = NOW() WHERE task_id = ?'
|
||||
);
|
||||
$stmt->execute([$status, $result, $id]);
|
||||
|
||||
echo json_encode(['ok' => true, 'id' => $id, 'status' => $status]);
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Atomically claim the oldest queued Web Designer task and print it as JSON.
|
||||
* Prints an empty JSON object ({}) when the queue is empty. Used by the console
|
||||
* runner's drain loop (agents/console/server.mjs) — the runner has no DB driver,
|
||||
* so it shells out to this.
|
||||
*
|
||||
* php api/cli/tasks-next.php
|
||||
*
|
||||
* The claim is a single conditional UPDATE (status queued -> running) guarded by
|
||||
* task_id, so two concurrent callers can never claim the same row.
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
require __DIR__ . '/../config.php';
|
||||
|
||||
$pdo = new PDO(
|
||||
sprintf('mysql:host=%s;dbname=%s;charset=utf8mb4', DB_HOST, DB_NAME),
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
|
||||
);
|
||||
|
||||
// Find + claim in a loop: SELECT the next candidate, then a guarded UPDATE.
|
||||
// If the UPDATE affects 0 rows (someone else took it), try the next candidate.
|
||||
for ($attempt = 0; $attempt < 20; $attempt++) {
|
||||
$row = $pdo->query(
|
||||
"SELECT task_id FROM cja_tasks WHERE status = 'queued'
|
||||
ORDER BY sort_order ASC, task_id ASC LIMIT 1"
|
||||
)->fetch();
|
||||
|
||||
if (!$row) {
|
||||
echo "{}";
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int) $row['task_id'];
|
||||
$upd = $pdo->prepare(
|
||||
"UPDATE cja_tasks SET status = 'running', started_at = NOW()
|
||||
WHERE task_id = ? AND status = 'queued'"
|
||||
);
|
||||
$upd->execute([$id]);
|
||||
|
||||
if ($upd->rowCount() === 1) {
|
||||
$task = $pdo->prepare('SELECT task_id, title, target_page, prompt, draft, assets FROM cja_tasks WHERE task_id = ?');
|
||||
$task->execute([$id]);
|
||||
echo json_encode($task->fetch(), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
// lost the race — loop and grab the next one
|
||||
}
|
||||
|
||||
echo "{}";
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
-- Web Designer task queue — design requests the agent drains one at a time.
|
||||
--
|
||||
-- The admin submits a brief (target page, prompt, draft, assets) which lands
|
||||
-- here as `queued`. The console runner claims the oldest queued row, runs the
|
||||
-- design agent, builds, and auto-publishes (git commit), then marks it
|
||||
-- `published` (or `failed`). The queue is FIFO by (sort_order, task_id).
|
||||
--
|
||||
-- `assets` is JSON: { "images": [{ "url": "/media/x.webp", "alt": "" }],
|
||||
-- "videos": ["https://instagram.com/reel/..."] }
|
||||
-- `result` is JSON, written on completion: { commit, summary, live, error }.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cja_tasks` (
|
||||
`task_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
|
||||
`title` varchar(200) NOT NULL DEFAULT '',
|
||||
-- "/about", "/services", or "new:<slug>" to create a brand-new page
|
||||
`target_page` varchar(200) NOT NULL DEFAULT '',
|
||||
|
||||
`prompt` text DEFAULT NULL, -- the request / special instructions
|
||||
`draft` mediumtext DEFAULT NULL, -- optional draft content
|
||||
`assets` longtext DEFAULT NULL CHECK (json_valid(`assets`)),
|
||||
|
||||
`status` enum('queued','running','published','failed','canceled')
|
||||
NOT NULL DEFAULT 'queued',
|
||||
`result` longtext DEFAULT NULL CHECK (`result` IS NULL OR json_valid(`result`)),
|
||||
|
||||
`sort_order` int(11) NOT NULL DEFAULT 0,
|
||||
|
||||
`created_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||
`started_at` datetime DEFAULT NULL,
|
||||
`finished_at` datetime DEFAULT NULL,
|
||||
|
||||
PRIMARY KEY (`task_id`),
|
||||
KEY `idx_cja_tasks_queue` (`status`, `sort_order`, `task_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
|
@ -70,7 +70,6 @@ const { flush = false } = Astro.props;
|
|||
<li><a href="/resume" class="hover:text-foreground">Resume</a></li>
|
||||
<li><a href="/contact" class="hover:text-foreground">Contact</a></li>
|
||||
<li><a href="/changelog" class="hover:text-foreground">Changelog</a></li>
|
||||
<li><a href="/zzz-queue-test" class="hover:text-foreground">Queue Test</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ const nav = [
|
|||
{ to: "/about", label: "About" },
|
||||
{ to: "/resume", label: "Resume" },
|
||||
{ to: "/contact", label: "Contact Me" },
|
||||
{ to: "/zzz-queue-test", label: "Queue Test" },
|
||||
];
|
||||
|
||||
const current = Astro.url.pathname.replace(/\/$/, "") || "/";
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
import { SITE } from "../lib/blog-data.js";
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title={`Queue Test — ${SITE.name}`}
|
||||
description="Temporary test page for queue validation."
|
||||
canonical="/zzz-queue-test"
|
||||
>
|
||||
<section class="mx-auto w-full max-w-6xl px-5 pt-20 pb-14 md:pt-28">
|
||||
<p class="font-mono text-xs tracking-[0.18em] text-muted-foreground uppercase">Internal</p>
|
||||
<h1
|
||||
class="mt-6 max-w-[18ch] font-serif text-[clamp(2.2rem,5.6vw,4.2rem)] leading-[1.04] tracking-tight text-balance"
|
||||
>
|
||||
Queue Test
|
||||
</h1>
|
||||
<p class="mt-7 max-w-[54ch] font-serif text-[clamp(1.1rem,2.2vw,1.4rem)] leading-snug text-[var(--ca-ink-2)]">
|
||||
This is a temporary placeholder page used to validate the publishing queue. It will be removed once testing is complete.
|
||||
</p>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
Loading…
Reference in a new issue