Are you trying to retrieve a key/value that was removed? Bit more context would be helpful
Are you trying to retrieve a key/value that was removed? Bit more context would be helpful
Specifically for Durable Object classes with SQLite storage backend, KV operations which were previously asynchronous (for example, get, put, delete, deleteAll, list) are synchronous, even though they return promises. These methods will have completed their operations before they return the promise.
runDurableObjectAlarm() return true or a similar value?while (true) what about while (ran)? Declare ran as true before the first runawait to be consistent with the API that you need to await a Promise. The underlying behavior doesn't change.await of a promise will be more confused, rather than having to read all the DO docs to figure out that it doesn't matter.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?let ran = false;
ran = await runDurableObjectAlarm(stub) // ran = true
ran = await runDurableObjectAlarm(stub) // ran = true
ran = await runDurableObjectAlarm(stub) // ran = true
ran = await runDurableObjectAlarm(stub) // ran = true
ran = await runDurableObjectAlarm(stub) // ran = falsewhile (true) {
let ran = await runDurableObjectAlarm(stub)
if (!ran) {
break
};
}while (true)while (ran)ran> select * from _cf_KV;
access to _cf_KV.key is prohibited: SQLITE_AUTHblockConcurrencyWhileblockConcurrencyWhileblockConcurrencyWhileblockConcurrencyWhilestorage.getstorage.getstorage.setstorage.setapplyMigration.thenafterinitializedthis.someStatethis.someState = -1ctx.blockConcurrencyWhile(...)applyMigrationstransaction(...)await this.#_config.doStorage.put<number>(this.#_lastMigrationIDKeyName(), this.#_lastMigrationMonotonicId);SELECT name FROM sqlite_master WHERE type='table' AND name=?;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(...)
})
}