alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
80 lines (69 loc) • 2.39 kB
text/typescript
import { $hook, $inject, Alepha } from "alepha";
import { $logger } from "alepha/logger";
import { $consumer } from "../primitives/$consumer.ts";
import { $queue } from "../primitives/$queue.ts";
import { WorkerProvider } from "./WorkerProvider.ts";
// ---------------------------------------------------------------------------------------------------------------------
/**
* Cloudflare Workers queue consumer provider.
*
* Replaces the polling-based `WorkerProvider` in Cloudflare Workers.
* Instead of running a polling loop, this provider hooks into `cloudflare:queue`
* events emitted by the CF Workers `queue` handler.
*
* @see https://developers.cloudflare.com/queues/
*/
export class WorkerdWorkerProvider extends WorkerProvider {
protected override readonly alepha = $inject(Alepha);
protected override readonly log = $logger();
/**
* Override start hook — collect consumers but do NOT start polling workers.
*/
protected override readonly start = $hook({
on: "start",
priority: "last",
handler: () => {
for (const queue of this.alepha.primitives($queue)) {
const handler = queue.options.handler;
if (handler) {
this.consumers.push({ handler, queue });
}
}
for (const consumer of this.alepha.primitives($consumer)) {
this.consumers.push(consumer.options);
}
if (this.consumers.length > 0) {
this.log.debug(
`Registered ${this.consumers.length} queue consumer${this.consumers.length > 1 ? "s" : ""} for Cloudflare Queue.`,
);
}
},
});
/**
* Override stop hook — no workers to stop on Cloudflare.
*/
protected override readonly stop = $hook({
on: "stop",
handler: () => {},
});
/**
* Handle incoming messages from Cloudflare Queue.
*/
protected readonly onQueueMessage = $hook({
on: "cloudflare:queue",
handler: async (event: { queue: string; message: string }) => {
const consumer = this.consumers.find((c) => c.queue.name === event.queue);
if (!consumer) {
this.log.warn(
`No consumer found for queue '${event.queue}', skipping message.`,
);
return;
}
await this.processMessage({ message: event.message, consumer });
},
});
/**
* No-op on Cloudflare — no workers to wake.
*/
public override wakeUp(): void {}
}