2.0.0-beta.54 - Queues in Dev Mode
Cloudflare Queues now work end-to-end in alchemy dev. The local
Cloudflare runtime emulates both the queue and its consumer, so the
same Worker that produces and consumes messages in production runs
unchanged on your laptop — send a message on one route and your
consumer handler fires locally, no Cloudflare round-trip.
Queues and consumers in alchemy dev
Section titled “Queues and consumers in alchemy dev”One Worker, both halves: Cloudflare.Queue.bind gives you the
producer, Cloudflare.messages(queue).subscribe registers the
consumer (#571):
export default class MyWorker extends Cloudflare.Worker<MyWorker>()( "MyWorker", { main: import.meta.filename }, Effect.gen(function* () { const queue = yield* Cloudflare.Queue("MyQueue"); const producer = yield* Cloudflare.Queue.bind(queue);
// consumer — fires locally under `alchemy dev` yield* Cloudflare.messages<{ text: string }>(queue).subscribe( (stream) => Stream.runForEach(stream, (msg) => handle(msg.body)), );
return { fetch: Effect.gen(function* () { const request = yield* HttpServerRequest.HttpServerRequest; const body = yield* request.json; yield* producer.send(body).pipe(Effect.orDie); return yield* HttpServerResponse.json({ sent: body }); }), }; }).pipe( Effect.provide([ Cloudflare.QueueBindingLive, Cloudflare.QueueEventSourceLive, ]), ),) {}Under alchemy dev, the queue and consumer are provisioned by local
providers: they get dev: IDs instead of live Cloudflare IDs, and the
local runtime keeps its storage under .alchemy/local.
On your first real alchemy deploy, the providers’ diff logic
recognizes the dev: ID and upgrades the resource in place — an
update that creates the live queue and consumer under the same logical
resource, never a replacement. And destroying a stack that only ever
ran locally skips the Cloudflare API entirely.
QueueConsumer also now persists deadLetterQueue and settings
(batch size, concurrency, retries — see the new exported
QueueConsumerSettings interface) in its attributes, so consumer
config reconciles like everything else.
Also in this release
Section titled “Also in this release”alchemy devno longer requires Cloudflare credentials at startup — the local runtime resolves the account ID lazily, only when a live API call actually needs it (#578).- PlanetScale providers are more resilient to live API timing — branch promote/demote retries while a cluster resize is still finalizing, Postgres resizes wait for the branch to finish provisioning first, and polling budgets grew from 10 to 30 minutes (60 for Postgres cluster-size changes) (#576).