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
6 changes: 6 additions & 0 deletions src/workerd/api/tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ wd_test(
data = ["actor-alarms-test.js"],
)

wd_test(
src = "actor-alarms-in-memory-test.wd-test",
args = ["--experimental"],
data = ["actor-alarms-in-memory-test.js"],
)

wd_test(
src = "actor-alarms-name-test.wd-test",
args = ["--experimental"],
Expand Down
60 changes: 60 additions & 0 deletions src/workerd/api/tests/actor-alarms-in-memory-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2023 Cloudflare, Inc.
// Licensed under the Apache 2.0 license found in the LICENSE file or at:
// https://opensource.org/licenses/Apache-2.0

import * as assert from 'node:assert';

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

async waitForAlarm(scheduledTime) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
let self = this;
const { promise, resolve, reject } = Promise.withResolvers();
self.resolve = resolve;
self.reject = reject;

try {
await promise;
if (Date.now() < scheduledTime.valueOf()) {
throw new Error(
`Date.now() is before scheduledTime! ${Date.now()} vs ${scheduledTime.valueOf()}`
);
}
} catch (e) {
throw new Error(
`error waiting for alarm at ${scheduledTime.valueOf()}: ${e}`
);
}

let alarm = await this.state.storage.getAlarm();
if (alarm != null) {
throw new Error(`alarm time not cleared when handler ends. ${alarm}`);
}
}

async fetch() {
const time = Date.now() + 50;
this.scheduledTime = time;
await this.state.storage.setAlarm(time);
assert.equal(await this.state.storage.getAlarm(), time);

await new Promise(resolve => setTimeout(resolve, 200));

return new Response('OK');
}

async alarm() {}
}

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');
let text = await res.text();
assert.equal(text, 'OK');
},
};
26 changes: 26 additions & 0 deletions src/workerd/api/tests/actor-alarms-in-memory-test.wd-test
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Workerd = import "/workerd/workerd.capnp";

const config :Workerd.Config = (
services = [
(name = "main", worker = .mainWorker),
(name = "TEST_TMPDIR", disk = (writable = true)),
],
);

const mainWorker :Workerd.Worker = (
compatibilityFlags = ["experimental", "nodejs_compat"],

modules = [
(name = "worker", esModule = embed "actor-alarms-in-memory-test.js"),
],

durableObjectNamespaces = [
(className = "DurableObjectExample", uniqueKey = "210bd0cbd803ef7883a1ee9d86cce06e"),
],

durableObjectStorage = (inMemory = void),

bindings = [
(name = "ns", durableObjectNamespace = "DurableObjectExample"),
],
);
3 changes: 2 additions & 1 deletion src/workerd/io/worker.c++
Original file line number Diff line number Diff line change
Expand Up @@ -4234,7 +4234,8 @@ void Worker::Actor::assertCanSetAlarm() {

void Worker::Actor::Impl::HooksImpl::updateAlarmInMemory(kj::Maybe<kj::Date> newTime) {
if (newTime == kj::none) {
maybeAlarmPreviewTask = kj::none;
auto task = kj::mv(maybeAlarmPreviewTask);
maybeAlarmPreviewTask = kj::evalLater([task = kj::mv(task)]() mutable { task = kj::none; });
return;
}

Expand Down
Loading