Hat Ihre SvelteKit-App Probleme mit Aufgaben wie dem Versenden von E-Mails, der Größenänderung von Bildern oder der Verarbeitung von Daten? Mit BullMQ können Sie diese schweren Aufgaben in den Hintergrund verlagern und Ihre App blitzschnell halten. In diesem Beitrag zeigen wir Ihnen, wie Sie es einrichten und reale Aufgaben wie ein Profi bewältigen. Lasst uns eintauchen!
tl;dr Richten Sie BullMQ-Worker in Hooks.server.js ein. Schauen Sie sich das Beispiel an
BullMQ ist eine Node.js-Bibliothek zum Erstellen und Verwalten von Jobwarteschlangen mit Redis. Es hilft Ihnen, zeitaufwändige Aufgaben effizient im Hintergrund auszuführen. Mit integrierten Funktionen wie Wiederholungsversuchen, Auftragsplanung und Parallelitätskontrolle macht BullMQ die Handhabung komplexer Arbeitsabläufe in Ihrer App einfach und zuverlässig.
Installieren Sie zunächst ioredis (Redis-Client für node.js) und bullmq:
pnpm i -D ioredis bullmq
Auch wenn Sie aus einer serverlosen Umgebung wie Vercel Jobs zu einer Bullmq-Warteschlange hinzufügen können, müssen die Worker auf einem herkömmlichen, langlebigen node.js-Server ausgeführt werden. Ersetzen Sie daher „adapter-auto“ durch „adapter-node:
“.
pnpm rm @sveltejs/adapter-auto && pnpm i -D @sveltejs/adapter-node
Vergessen Sie nicht, Ihre Svelte-Konfiguration (svelte.config.js) mit dem neu installierten Knotenadapter zu aktualisieren.
Als nächstes richten wir eine BullMQ-Jobwarteschlange und ihren Prozessor ein. Erstellen Sie eine .js-Datei im Verzeichnis src/lib/server/:
// src/lib/server/background-jobs.js import { REDIS_URL } from "$env/static/private"; import { Queue, Worker } from "bullmq"; import IORedis from "ioredis"; const Q_NAME = "q"; export const jobsQueue = new Queue(Q_NAME, { connection: new IORedis(REDIS_URL), }); const sleep = (t) => new Promise((resolve) => setTimeout(resolve, t * 100)); export const setupBullMQProcessor = () => { new Worker( Q_NAME, async (job) => { for (let i = 0; i <= 100; i++) { await sleep(Math.random()); await job.updateProgress(i); await job.log(`Processing job at interval ${i}`); if (Math.random() * 200 < 1) throw new Error(`Random error at ${i}`); } return `This is the return value of job (${job.id})`; }, // https://docs.bullmq.io/bull/patterns/persistent-connections#maxretriesperrequest { connection: new IORedis(REDIS_URL, { maxRetriesPerRequest: null }) } ); };
Hier haben wir auch eine Hilfsfunktion erstellt, die einen BullMQ-Worker instanziiert, der auf Jobs in der Warteschlange Q_NAME wartet und diese verarbeitet.
Wir müssen diese Funktion in unserer Datei „hooks.server.js“ aufrufen – entweder auf der obersten Ebene oder innerhalb des Init-Hooks.
// src/hooks.server.js // ... import { building } from "$app/environment"; import { setupBullMQProcessor } from "$lib/server/background-jobs"; // ... if (!building) { setupBullMQProcessor(); } // ...
Die !building-Prüfung überspringt das Einrichten des Workers (und damit einer Redis-Verbindung) während des Builds und beschleunigt so den Prozess.
? BullMQ kann jetzt in unserer SvelteKit-App verwendet werden ?
Um das Setup zu testen, erstellen wir einen POST-Endpunkt, um einen Job in die Warteschlange zu stellen.
// src/routes/+server.ts import { jobsQueue } from "$lib/server/background-jobs"; export const POST = async () => { const { id: jobId } = await jobsQueue.add("job", {}); /* The following code passes the job's progress to the client as a stream. If you don't need to update the client with the progress, you can skip the following. You can also use web-sockets or polling for that. */ const stream = new ReadableStream({ async pull(controller) { const job = await jobsQueue.getJob(jobId); controller.enqueue( JSON.stringify( job.failedReason ? { error: job.failedReason } : job.returnvalue ? { data: job.returnvalue } : { progress: job.progress } ) ); controller.enqueue("\n"); if (job.finishedOn) { controller.close(); } // wait for 1-second before sending the next status update await new Promise((r) => setTimeout(r, 1e3)); }, }); return new Response(stream, { headers: { "content-type": "text/plain" }, }); };
Und im Frontend fügen wir eine Schaltfläche hinzu, um den oben genannten Endpunkt auszulösen und anschließend den Status des Jobs anzuzeigen:
<!-- src/routes/+page.svelte --> <script> let result = $state(); $inspect(result); const handleClick = async () => { const response = await fetch("/", { method: "post" }); const reader = await response.body.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; result = JSON.parse(new TextDecoder().decode(value)); } setTimeout(() => (result = undefined), 3e3); }; </script> {#if result?.error} <div> <p>Here is the output:</p> <p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/173785153552047.jpg" class="lazy" alt="background jobs demo using sveltekit and bullmq" loading="lazy" style="max-width:90%" style="max-width:90%" data-animated="true"></p> <hr> <h3> Bonus ? </h3> <p>You can also mount a bull-board dashboard in your SvelteKit app for easy monitoring of background jobs.</p> <p>Install bull-board dependencies<br> </p> <pre class="brush:php;toolbar:false">pnpm i -D @bull-board/api @bull-board/hono @hono/node-server hono
und ändern Sie Ihre Hooks.server.js:
// src/hooks.server.js import { building } from "$app/environment"; import { jobsQueue, setupBullMQProcessor } from "$lib/server/background-jobs"; import { createBullBoard } from "@bull-board/api"; import { BullMQAdapter } from "@bull-board/api/bullMQAdapter"; import { HonoAdapter } from "@bull-board/hono"; import { serveStatic } from "@hono/node-server/serve-static"; import { Hono } from "hono"; if (!building) { setupBullMQProcessor(); } const bullboard = (() => { const serverAdapter = new HonoAdapter(serveStatic); createBullBoard({ queues: [new BullMQAdapter(jobsQueue)], serverAdapter, }); const app = new Hono({ strict: false }); const basePath = "/jobs"; serverAdapter.setBasePath(basePath); app.route(basePath, serverAdapter.registerPlugin()); return app; })(); export const handle = async ({ event, resolve }) => { if (event.url.pathname.match(/^\/jobs($|\/)/)) { return bullboard.fetch(event.request); } return resolve(event); };
Dann besuchen Sie
Das obige ist der detaillierte Inhalt vonHintergrundjobs in SvelteKit mit BullMQ. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!