Improve event timeout with heartbeat_at
This commit is contained in:
@@ -10,6 +10,7 @@ export async function up(db: Kysely<any>): Promise<void> {
|
|||||||
.addColumn("source", "text", (cb) => cb.notNull())
|
.addColumn("source", "text", (cb) => cb.notNull())
|
||||||
.addColumn("payload", "jsonb", (cb) => cb.notNull())
|
.addColumn("payload", "jsonb", (cb) => cb.notNull())
|
||||||
.addColumn("state", "jsonb")
|
.addColumn("state", "jsonb")
|
||||||
|
.addColumn("heartbeat_at", "timestamptz")
|
||||||
.addColumn("started_at", "timestamptz")
|
.addColumn("started_at", "timestamptz")
|
||||||
.addColumn("ended_at", "timestamptz")
|
.addColumn("ended_at", "timestamptz")
|
||||||
.addColumn("available_at", "timestamptz", (cb) => cb.notNull().defaultTo(sql`now()`))
|
.addColumn("available_at", "timestamptz", (cb) => cb.notNull().defaultTo(sql`now()`))
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ import { env } from "../util";
|
|||||||
|
|
||||||
const DOMAIN = "dev.api.bladeandbrawn.com";
|
const DOMAIN = "dev.api.bladeandbrawn.com";
|
||||||
|
|
||||||
const PRINTFUL_WEBHOOK_URL = `http://${DOMAIN}/webhooks/printful?secret=${env.PRINTFUL_WEBHOOK_SECRET}`;
|
const PRINTFUL_WEBHOOK_URL = env.NODE_ENV === "development" ?
|
||||||
|
`http://${DOMAIN}/webhooks/printful?secret=${env.PRINTFUL_WEBHOOK_SECRET}` :
|
||||||
|
`https://${DOMAIN}/webhooks/printful?secret=${env.PRINTFUL_WEBHOOK_SECRET}`;
|
||||||
|
// http dosent work for webflow, so cant register properly for development env
|
||||||
const WEBFLOW_WEBHOOK_URL = `https://${DOMAIN}/webhooks/webflow`;
|
const WEBFLOW_WEBHOOK_URL = `https://${DOMAIN}/webhooks/webflow`;
|
||||||
|
|
||||||
function printError(err: unknown): never {
|
function printError(err: unknown): never {
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ export class EventQueue<G extends string, T extends Record<string, EventTypeOpti
|
|||||||
if (!front) return;
|
if (!front) return;
|
||||||
|
|
||||||
const result = await db.updateTable("events")
|
const result = await db.updateTable("events")
|
||||||
.set({ started_at: new Date() })
|
.set({ started_at: new Date(), heartbeat_at: new Date() })
|
||||||
.where("id", "=", front.id)
|
.where("id", "=", front.id)
|
||||||
.where("started_at", "is", null)
|
.where("started_at", "is", null)
|
||||||
.where((eb) =>
|
.where((eb) =>
|
||||||
@@ -195,7 +195,7 @@ export class EventQueue<G extends string, T extends Record<string, EventTypeOpti
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Value.Assert(typeCfg.schemas.payload, event.payload);
|
Value.Assert(typeCfg.schemas.payload, event.payload);
|
||||||
await typeCfg.processor(event.payload, (state) => this.Events.setState(event.id, state), event.id);
|
await typeCfg.processor(event.payload, (s) => this.Events.setState(event.id, s), event.id);
|
||||||
await this.Events.resolve(event.id);
|
await this.Events.resolve(event.id);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -236,6 +236,7 @@ export class EventQueue<G extends string, T extends Record<string, EventTypeOpti
|
|||||||
.set((eb) => ({
|
.set((eb) => ({
|
||||||
errors: type === "error" ? eb("errors", "+", 1) : eb.ref("errors"),
|
errors: type === "error" ? eb("errors", "+", 1) : eb.ref("errors"),
|
||||||
rate_limits: type === "ratelimit" ? eb("rate_limits", "+", 1) : eb.ref("rate_limits"),
|
rate_limits: type === "ratelimit" ? eb("rate_limits", "+", 1) : eb.ref("rate_limits"),
|
||||||
|
heartbeat_at: null,
|
||||||
started_at: null,
|
started_at: null,
|
||||||
ended_at: null,
|
ended_at: null,
|
||||||
has_failed: false,
|
has_failed: false,
|
||||||
|
|||||||
@@ -89,9 +89,12 @@ export class EventsService {
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
async setState(id: string, state: JsonValue) {
|
async setState(id: string, state: JsonValue, shouldHeartbeat: boolean = true) {
|
||||||
await db.updateTable("events")
|
await db.updateTable("events")
|
||||||
.set({ state })
|
.set((eb) => ({
|
||||||
|
state,
|
||||||
|
heartbeat_at: shouldHeartbeat ? new Date() : eb.ref("heartbeat_at")
|
||||||
|
}))
|
||||||
.where("id", "=", id)
|
.where("id", "=", id)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
@@ -125,6 +128,7 @@ export class EventsService {
|
|||||||
async retry(id: string): Promise<boolean> {
|
async retry(id: string): Promise<boolean> {
|
||||||
const result = await db.updateTable("events")
|
const result = await db.updateTable("events")
|
||||||
.set({
|
.set({
|
||||||
|
heartbeat_at: null,
|
||||||
started_at: null,
|
started_at: null,
|
||||||
ended_at: null,
|
ended_at: null,
|
||||||
has_failed: false,
|
has_failed: false,
|
||||||
@@ -147,7 +151,7 @@ export class EventsService {
|
|||||||
}))
|
}))
|
||||||
.where("started_at", "is not", null)
|
.where("started_at", "is not", null)
|
||||||
.where("ended_at", "is", null)
|
.where("ended_at", "is", null)
|
||||||
.where("started_at", "<", new Date(Date.now() - EventsService.CONCURRENCY_TIMEOUT_MS))
|
.where("heartbeat_at", "<", new Date(Date.now() - EventsService.CONCURRENCY_TIMEOUT_MS))
|
||||||
.$if(opt.filter?.type !== undefined, (qb) => qb.where("type", "=", opt.filter!.type!))
|
.$if(opt.filter?.type !== undefined, (qb) => qb.where("type", "=", opt.filter!.type!))
|
||||||
.$if(opt.filter?.group !== undefined, (qb) => qb.where("group", "=", opt.filter!.group!))
|
.$if(opt.filter?.group !== undefined, (qb) => qb.where("group", "=", opt.filter!.group!))
|
||||||
.returning(["id"])
|
.returning(["id"])
|
||||||
|
|||||||
Reference in New Issue
Block a user