Durable Objects
Per-id serialized state and alarms, backed by synchronous storage calls.
Configuration
"durable_objects": { "COUNTER": "Counter" }
The binding name maps to a class declared in the entry file, above the default export.
Usage
class Counter {
constructor(state, env) { this.state = state; this.env = env; }
// Synchronous, like every other binding: state.storage.* are blocking calls.
fetch(request) {
const n = (this.state.storage.get("n") || 0) + 1;
this.state.storage.put("n", n);
// Debounced: a burst of requests produces one alarm, not one per request.
this.state.storage.setAlarm(Date.now() + 1000);
return Response.json({ n });
}
// Runs later, with no request in flight.
async alarm() {
await this.env.DB.prepare("INSERT INTO rollup (n) VALUES (?)").bind(this.state.storage.get("n")).run();
}
}
export default {
fetch(request) {
const id = env.COUNTER.idFromName("global");
return env.COUNTER.get(id).fetch(request);
},
};
Storage and alarms
state.storage has get, put, delete, deleteAll, list({ prefix?, limit? }) (a Map), setAlarm(time), getAlarm() and deleteAlarm(). Each object has at most one pending alarm; a later setAlarm replaces it. state.waitUntil(promise) works as in a handler.
The namespace has idFromName(name), idFromString(hex), newUniqueId() and get(id).
Related
- D1-compatible SQLite: for data shared across objects