Getting Started
用意するもの
- Workers Paidプランの有効なCloudflareアカウント(SQLite版のDurable ObjectsとQueuesの両方が要求)
compatibility_dateは2025-11-17以降(自己参照のservice bindingをctx.exportsで解決するため)
インストール
bash
pnpm create cloudflare@latest my-jobs --type=hello-world
cd my-jobs
pnpm add tsumugiリソース作成
D1とQueuesを先に作ります
bash
pnpm wrangler d1 create my-jobs
pnpm wrangler queues create my-jobswrangler.jsonc
Tsumugiが使うbindingは4つです
jsonc
{
"name": "my-jobs",
"main": "src/index.ts",
"compatibility_date": "2026-07-01",
"durable_objects": {
"bindings": [{ "name": "JOB_SHARD", "class_name": "TsumugiJobShard" }],
},
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["TsumugiJobShard"] }],
"d1_databases": [
{
"binding": "TSUMUGI_DB",
"database_name": "my-jobs",
"database_id": "d1 createが出力したid",
// 読み取りモデルのマイグレーションはパッケージに同梱
"migrations_dir": "./node_modules/tsumugi/migrations",
},
],
"queues": {
"producers": [{ "binding": "TSUMUGI_QUEUE", "queue": "my-jobs" }],
"consumers": [{ "queue": "my-jobs", "max_batch_size": 10, "max_retries": 5 }],
},
"analytics_engine_datasets": [{ "binding": "TSUMUGI_METRICS", "dataset": "tsumugi_jobs" }],
// D1の読み取りモデルのcleanupをscheduledで実行
"triggers": { "crons": ["0 * * * *"] },
}INFO
max_retriesはTsumugiの試行回数とは無関係です。consumerは結果をDurable Objectへ報告したあと必ず即ackするので、Queues側のretryは配送そのものが失敗したときにしか効きません
読み取りモデルの作成
一覧と検索が参照するD1のテーブルを作成します
bash
pnpm wrangler d1 migrations apply my-jobs --local
pnpm wrangler d1 migrations apply my-jobs --remoteWorker
performerを定義して、defineTsumugiに登録簿として渡します
ts
import { bearerAuth, defineTsumugi, enqueue } from 'tsumugi';
import { Performer } from 'tsumugi/performer';
import { ui } from 'tsumugi/ui';
class Hello extends Performer<{ name: string }, void, {}, Env> {
async perform(payload: { name: string }): Promise<void> {
console.log(`hello, ${payload.name}`);
}
}
const tsumugi = defineTsumugi<Env>({
performers: { HELLO: Hello },
auth: bearerAuth((env: Env) => env.TSUMUGI_TOKEN, { cookie: 'tsumugi_token' }),
ui: ui({ tokenCookie: 'tsumugi_token' }),
});
// Durable Objectクラスの再エクスポートが要る
export { TsumugiJobShard } from 'tsumugi';
export default {
...tsumugi,
async fetch(request, env, ctx) {
const { pathname } = new URL(request.url);
if (pathname === '/enqueue') {
const id = await enqueue(env, { binding: 'HELLO', payload: { name: 'world' } });
return Response.json({ id });
}
// 残りはダッシュボードとREST APIへ
return tsumugi.fetch!(request, env, ctx);
},
} satisfies ExportedHandler<Env>;defineTsumugiが返すのはfetchとqueueとscheduledを持つハンドラです 独自のfetchを追加する場合は上のようにスプレッドし、処理しなかったパスをtsumugi.fetchへ渡します
トークンの設定
認証はfail-closedです。設定するまでREST APIもダッシュボードも404を返します
bash
pnpm wrangler secret put TSUMUGI_TOKENローカルで動かすときは.dev.varsに書きます
TSUMUGI_TOKEN=ローカル用のトークン起動
bash
pnpm wrangler dev/enqueueにアクセスするとジョブIDが返ります。/を開くとダッシュボードが表示されるので、トークンを入力すると一覧を確認できます