do cloudflare devs have some internal library for testing DOs
do cloudflare devs have some internal library for testing DOs
blockConcurrencyWhile when applying migration in constructor, and also I can put the entire migration into a transactionSync to prevent the rare event that migrations succeeded but writing migration number fails.transaction()? blockConcurrencyWhile has a different purpose than sync/async.storage.get/storage.set's implementations are sync, because applyMigration is async, .then puts continuation in the next event loop, so the log order will be before -> after -> initialized. I haven't tested it but unless DO has a different behavior to regular JS, that should be the case.this.someState is still undefined) by the end of current event loop. I don't know if DO is able to process messages in the same event loop as the one doing the construction, but if that's true, then that's an issue.blockConcurrencyWhile is a workaround, but if we had an actual sync API, we wouldn't even need it.this.someState = -1 before the call to ctx.blockConcurrencyWhile(...) and then the property won't be considered optional.blockConcurrencyWhile at all, because applyMigrations can just be sync.storage.get/storage.set is async, you also couldn't do:await puts continuation in the next event loop, by which point transactionSync already exited.transaction(...) which is async. Anyway, we seem to be going in circles transaction with SQLite?When using the SQLite-backed storage engine, the txn object is obsolete. Any storage operations performed directly on the ctx.storage object, including SQL queries using ctx.storage.sql.exec(), will be considered part of the transaction.You can use both APIs, KV and SQL, inside an SQLite DO.
transactionSync with SQLite.transaction(...), so what you suggest could be done by starting one in one fetch/rpc call, but without awaiting the returned promise and just storing it in-memory. Then another request can await for it when needed.transaction() method.Error: Durable Object test helpers can only be used with stubs pointing to objects defined within the same worker.
state.storage.deleteAll() to remove an old instance. An old instance will not incur any request or duration charges if they aren't being accessed, but their used storage will be charged until deletedblockConcurrencyWhileblockConcurrencyWhileblockConcurrencyWhileblockConcurrencyWhiletransactionSynctransactionSynctransactionSynctransaction()transaction()storage.getstorage.getstorage.setstorage.setapplyMigration.thenbeforeafterinitializedthis.someStatethis.someState = -1ctx.blockConcurrencyWhile(...)applyMigrationstransaction(...)transaction(...)transactionfunction doX() {
this.promiseTxn = this.storage.transaction(async (txn) => {
const a = txn.get("keyA");
const nextRequestValue = await this.waitForAValueSetByAFutureRequest();
txn.put("keyB", a + nextRequestValue);
});
}state.storage.deleteAll()async function applyMigrations(storage: DurableObjectStorage) {
await storage.get(...)
// Do migration stuffs
await storage.set(...)
}class MyDO extends DurableObject {
someState!: number
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env)
console.log('before')
applyMigrations(ctx.storage).then(() => {
this.someState = 42
console.log('initialized')
})
console.log('after')
}
}async function applyMigrations(storage: DurableObjectStorage) {
storage.transactionSync(async () => {
const currentMigration = await storage.get(...)
// Do migration stuffs
await storage.set(...)
})
}// Using KV for simplicity
const a = txn.get("foo")txn.put("bar", a + "yo");miniflare: {
workers: [
{
name: "dummy-do",
modules: true,
scriptPath: "./test/database/mo.ts"
}
],
durableObjects: {
"MockSqlBackupDO": { className: "DummyDO", scriptName: "dummy-do", useSQLite: true }
}
}