Generalize queue logic

This commit is contained in:
Dominic Ferrando
2026-07-11 20:24:25 -04:00
parent d40b9209d5
commit d17b3d8960
3 changed files with 189 additions and 174 deletions
+18 -19
View File
@@ -189,21 +189,20 @@ export const app = new Elysia()
.group("/sync", (app) => app
// Sync status
.get("/", async ({ sessionId }) => {
const latestSync = await s.Commerce.Sync.getLatest(sessionId);
if (!latestSync) throw new NotFoundError("No sync found");
return {
startDate: latestSync.started_at,
status: s.Commerce.Sync.deriveStatus(latestSync),
syncingPProductIds: latestSync.syncing_p_product_ids
}
const syncState = await s.Commerce.ProductSync.getSessionSyncState(sessionId);
if (!syncState) throw new NotFoundError("No product sync found for the provided session");
return syncState;
})
// Run sync
.post("/:pProductId?", async ({ params: { pProductId }, sessionId }) => {
await s.Commerce.Sync.start({
await s.Commerce.ProductSync.Queue.enqueue({
session: { id: sessionId, name: "Portal" },
filter: {
pProductIds: pProductId ? [pProductId] : null
}
}).then(async (id) => {
await s.Commerce.ProductSync.Queue.drain({ untilId: id });
void s.Commerce.ProductSync.Queue.drain().catch((err) => log.error({ err }));
});
}, { params: t.Object({ pProductId: t.Optional(t.Numeric()) }) }),
)
@@ -232,11 +231,17 @@ export const app = new Elysia()
const pProduct = payload.data.sync_product;
log.info({ productId: pProduct.id }, "printful webhook: product updated");
await s.Commerce.Sync.start({
// Controller layer handles draining the queue, potentionally across multiple workers
// TODO: maybe find better way of handling queue draining
// can cause a worker to hang for long time while draining
// this can cause an issue with webhook sender timing out and sending duplicate payload
// while we wait to process unrelated events
await s.Commerce.ProductSync.Queue.enqueue({
session: { id: randomUUIDv7(), name: "Printful" },
filter: {
pProductIds: [pProduct.id]
}
filter: { pProductIds: [pProduct.id] }
}).then(async (id) => {
await s.Commerce.ProductSync.Queue.drain({ untilId: id });
void s.Commerce.ProductSync.Queue.drain().catch((err) => log.error({ err }));
});
break;
}
@@ -311,13 +316,7 @@ app.listen(3000, async () => {
if (cluster.worker?.id === 1) {
log.info({ port: 3000 }, "server started")
try {
const frontQueuedSync = await s.Commerce.Sync.Queue.front();
if (frontQueuedSync) await s.Commerce.Sync.start(frontQueuedSync);
}
catch (err) {
log.error({ err }, "failed to resume product sync queue")
}
await s.Commerce.ProductSync.Queue.drain().catch((err) => log.error({ err }));
}
});