Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/workerd/api/actor-state.c++
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,10 @@ jsg::Promise<void> DurableObjectStorage::deleteAll(
auto traceContext = context.makeUserTraceSpan("durable_object_storage_deleteAll"_kjc);
auto options = configureOptions(kj::mv(maybeOptions).orDefault(PutOptions{}));

auto deleteAll = cache->deleteAll(options, context.getCurrentTraceSpan());
DeleteAllOptions deleteAllOptions{
.deleteAlarm = FeatureFlags::get(js).getDeleteAllDeletesAlarm(),
};
auto deleteAll = cache->deleteAll(options, context.getCurrentTraceSpan(), deleteAllOptions);

context.addTask(updateStorageDeletes(context, currentActorMetrics(), kj::mv(deleteAll.count)));

Expand Down
6 changes: 6 additions & 0 deletions src/workerd/api/tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ wd_test(
data = ["actor-alarms-delete-test.js"],
)

wd_test(
src = "delete-all-deletes-alarm-test.wd-test",
args = ["--experimental"],
data = ["delete-all-deletes-alarm-test.js"],
)

wd_test(
src = "actor-alarms-test.wd-test",
args = ["--experimental"],
Expand Down
70 changes: 70 additions & 0 deletions src/workerd/api/tests/delete-all-deletes-alarm-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Tests that the delete_all_deletes_alarm compat flag correctly controls whether
// deleteAll() also deletes alarms. This file is used by two test services: one
// with the flag enabled and one with it disabled. The EXPECT_ALARM_DELETED binding
// tells this code which behavior to expect.

import * as assert from 'node:assert';

export class DurableObjectExample {
constructor(state) {
this.state = state;
}

async fetch(request) {
const url = new URL(request.url);
const expectDeleted = url.searchParams.get('expectDeleted') === 'true';

// Set an alarm for 10 minutes from now.
const alarmTime = Date.now() + 10 * 60 * 1000;
await this.state.storage.setAlarm(alarmTime);
assert.equal(await this.state.storage.getAlarm(), alarmTime);

// Also put some KV data so deleteAll has something to delete.
await this.state.storage.put('key', 'value');

// Call deleteAll().
await this.state.storage.deleteAll();

// KV data should always be deleted.
assert.equal(await this.state.storage.get('key'), undefined);

const alarmAfter = await this.state.storage.getAlarm();

if (expectDeleted) {
// With the compat flag enabled, the alarm should be deleted.
assert.equal(
alarmAfter,
null,
`Expected alarm to be null after deleteAll(), got ${alarmAfter}`
);
} else {
// Without the compat flag, the alarm should be preserved.
assert.equal(
alarmAfter,
alarmTime,
`Expected alarm to be preserved after deleteAll(), got ${alarmAfter}`
);
// Clean up the alarm so it doesn't fire during the test.
await this.state.storage.deleteAlarm();
}

return new Response('OK');
}

async alarm() {
// Should not be invoked during the test.
throw new Error('alarm handler unexpectedly invoked');
}
}

export const test = {
async test(ctrl, env, ctx) {
let id = env.ns.idFromName('A');
let obj = env.ns.get(id);
let res = await obj.fetch(
`http://foo/test?expectDeleted=${env.EXPECT_ALARM_DELETED}`
);
let text = await res.text();
assert.equal(text, 'OK');
},
};
38 changes: 38 additions & 0 deletions src/workerd/api/tests/delete-all-deletes-alarm-test.wd-test
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Workerd = import "/workerd/workerd.capnp";

const unitTests :Workerd.Config = (
services = [
( name = "delete-all-deletes-alarm-enabled",
worker = (
modules = [
( name = "worker", esModule = embed "delete-all-deletes-alarm-test.js" )
],
compatibilityFlags = ["experimental", "nodejs_compat", "delete_all_deletes_alarm"],
durableObjectNamespaces = [
(className = "DurableObjectExample", uniqueKey = "210bd0cbd803ef7883a1ee9d86cce06e"),
],
durableObjectStorage = (inMemory = void),
bindings = [
(name = "ns", durableObjectNamespace = "DurableObjectExample"),
(name = "EXPECT_ALARM_DELETED", text = "true"),
],
)
),
( name = "delete-all-preserves-alarm-disabled",
worker = (
modules = [
( name = "worker", esModule = embed "delete-all-deletes-alarm-test.js" )
],
compatibilityFlags = ["experimental", "nodejs_compat", "delete_all_preserves_alarm"],
durableObjectNamespaces = [
(className = "DurableObjectExample", uniqueKey = "310bd0cbd803ef7883a1ee9d86cce06f"),
],
durableObjectStorage = (inMemory = void),
bindings = [
(name = "ns", durableObjectNamespace = "DurableObjectExample"),
(name = "EXPECT_ALARM_DELETED", text = "false"),
],
)
),
],
);
Loading
Loading