Adapters

Adapters

Adapters bind a Shuttl app to the services around it without agent or trigger code naming a vendor. The host chooses the implementation (shuttl serve, deploy, or App.bindAdapter).

v1 exposes a work queue. Later adapters can add scheduler, secrets, and storage behind the same IPlatformAdapter surface.

For how fork and background jobs work, see the work queue.


Binding

If you do nothing, the app uses in-memory services:

import { App, InMemoryPlatformAdapter } from "@shuttl-io/core";

const app = new App("MyApp");
// app.adapter is InMemoryPlatformAdapter

app.bindAdapter(new InMemoryPlatformAdapter({
    concurrency: 8,
    maxAttempts: 5,
}));

shuttl serve starts queue consumers when the IPC server starts.


Interface

interface IPlatformAdapter {
    queue(): IWorkQueue;
}

interface IWorkQueue {
    enqueue(job: WorkJob): Promise<void>;
    subscribe(handler: IWorkHandler): void;
}

interface IWorkHandler {
    handle(job: WorkJob): Promise<void>;  // resolve = ack; throw = retry
}

A RabbitMQ (or SQS) adapter later implements IWorkQueue. Triggers keep calling next.enqueue / fork; they never import a broker.


Writing an adapter

Implement IPlatformAdapter and IWorkQueue:

  1. enqueue must persist (or accept) the job before resolving.
  2. subscribe should start competing consumers.
  3. handle resolve → ack. handle throw → increment attempt, backoff, retry. After max attempts, poison (DLQ or log).
  4. One work queue per app is enough.

Do not put broker types on ActivationArgs or on ITrigger.


Next steps