Upsert batch job function
This commit is contained in:
@@ -22,6 +22,7 @@ import { PerformTaskOperationService } from "./tasks/performTaskOperation.server
|
||||
import { ProcessCallbackTimeoutService } from "./tasks/processCallbackTimeout";
|
||||
import { ProbeEndpointService } from "./endpoints/probeEndpoint.server";
|
||||
import { PgNotifyService } from "./db/pgNotify.server";
|
||||
import { runMigrations } from "graphile-worker";
|
||||
|
||||
const workerCatalog = {
|
||||
indexEndpoint: z.object({
|
||||
@@ -122,7 +123,14 @@ if (env.NODE_ENV === "production") {
|
||||
}
|
||||
|
||||
export async function init() {
|
||||
await addMigrationDelayAndNotify();
|
||||
await detectAndPrepareForMigrations();
|
||||
|
||||
await runMigrations({
|
||||
connectionString: env.DATABASE_URL,
|
||||
schema: env.WORKER_SCHEMA,
|
||||
});
|
||||
|
||||
await upsertBatchJobFunction();
|
||||
|
||||
if (env.WORKER_ENABLED === "true") {
|
||||
await workerQueue.initialize();
|
||||
@@ -133,6 +141,45 @@ export async function init() {
|
||||
}
|
||||
}
|
||||
|
||||
async function upsertBatchJobFunction() {
|
||||
const prismaSchema = new URL(env.DATABASE_URL).searchParams.get("schema") ?? "public";
|
||||
|
||||
await prisma.$executeRawUnsafe(`
|
||||
CREATE OR REPLACE FUNCTION ${prismaSchema}.add_batch_job(
|
||||
job_key text,
|
||||
job_key_new int,
|
||||
task_identifier text,
|
||||
payload json,
|
||||
maximum_payloads int,
|
||||
run_at timestamptz
|
||||
) RETURNS ${env.WORKER_SCHEMA}.jobs AS $$
|
||||
DECLARE
|
||||
v_job ${env.WORKER_SCHEMA}.jobs;
|
||||
BEGIN
|
||||
IF json_typeof(payload) IS DISTINCT FROM 'array' THEN
|
||||
RAISE EXCEPTION 'Must only call add_batch_job with an array payload';
|
||||
END IF;
|
||||
|
||||
v_job := ${env.WORKER_SCHEMA}.add_job(
|
||||
identifier := task_identifier,
|
||||
payload := payload,
|
||||
run_at := run_at,
|
||||
job_key := job_key,
|
||||
job_key_mode := 'preserve_run_at'
|
||||
);
|
||||
|
||||
IF json_array_length(v_job.payload) >= maximum_payloads THEN
|
||||
UPDATE jobs SET run_at = NOW() WHERE jobs.id = v_job.id RETURNING * INTO v_job;
|
||||
-- lie that this job was just inserted so a worker picks it up ASAP
|
||||
PERFORM pg_notify('jobs:insert', '');
|
||||
END IF;
|
||||
|
||||
RETURN v_job;
|
||||
END
|
||||
$$ LANGUAGE plpgsql VOLATILE;
|
||||
`);
|
||||
}
|
||||
|
||||
async function graphileSchemaExists() {
|
||||
const schemaCount = await prisma.$executeRaw`
|
||||
SELECT schema_name FROM information_schema.schemata
|
||||
@@ -142,13 +189,7 @@ async function graphileSchemaExists() {
|
||||
return schemaCount === 1;
|
||||
}
|
||||
|
||||
/** Helper for graphile-worker v0.14.0 migration. No-op if already migrated. */
|
||||
async function addMigrationDelayAndNotify() {
|
||||
if (!(await graphileSchemaExists())) {
|
||||
// no schema yet, likely first start
|
||||
return;
|
||||
}
|
||||
|
||||
async function getLatestMigration() {
|
||||
const migrationQueryResult = await prisma.$queryRawUnsafe(`
|
||||
SELECT id FROM ${env.WORKER_SCHEMA}.migrations
|
||||
ORDER BY id DESC LIMIT 1
|
||||
@@ -160,10 +201,25 @@ async function addMigrationDelayAndNotify() {
|
||||
|
||||
if (!migrationResults.length) {
|
||||
// no migrations applied yet
|
||||
return -1;
|
||||
}
|
||||
|
||||
return migrationResults[0].id;
|
||||
}
|
||||
|
||||
/** Helper for graphile-worker v0.14.0 migration. No-op if already migrated. */
|
||||
async function detectAndPrepareForMigrations() {
|
||||
if (!(await graphileSchemaExists())) {
|
||||
// no schema yet, likely first start
|
||||
return;
|
||||
}
|
||||
|
||||
const latestMigration = migrationResults[0].id;
|
||||
const latestMigration = await getLatestMigration();
|
||||
|
||||
if (latestMigration < 0) {
|
||||
// no migrations found
|
||||
return;
|
||||
}
|
||||
|
||||
// the first v0.14.0 migration has ID 11
|
||||
if (latestMigration > 10) {
|
||||
|
||||
Reference in New Issue
Block a user