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
25 changes: 25 additions & 0 deletions test/src/durable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ use worker::{
pub struct MyClass {
state: State,
number: AssertUnwindSafe<Cell<usize>>,
ctor_name: Option<String>,
}

impl DurableObject for MyClass {
fn new(state: State, _env: Env) -> Self {
let ctor_name = state.id().name();
Self {
state,
number: AssertUnwindSafe(Cell::new(0)),
ctor_name,
}
}

Expand All @@ -38,6 +41,15 @@ impl DurableObject for MyClass {
.unwrap_or_else(|| "unknown".to_string());
Response::ok(format!("Hello from {name}!"))
}
"/ctor-name" => {
// Return the name captured in the constructor, verifying it
// is available before any request is handled.
let name = self
.ctor_name
.clone()
.unwrap_or_else(|| "unknown".to_string());
Response::ok(format!("Hello from {name}!"))
}
"/storage" => {
let storage = self.state.storage();
let map = [("one".to_string(), 1), ("two".to_string(), 2)]
Expand Down Expand Up @@ -212,6 +224,19 @@ pub async fn handle_hello(
stub.fetch_with_str("https://fake-host/hello").await
}

#[worker::send]
pub async fn handle_ctor_name(
_req: Request,
env: Env,
_data: crate::SomeSharedData,
) -> Result<Response> {
let namespace = env.durable_object("MY_CLASS")?;
let name = "my-durable-object";
let id = namespace.id_from_name(name)?;
let stub = id.get_stub()?;
stub.fetch_with_str("https://fake-host/ctor-name").await
}

#[worker::send]
pub async fn handle_hello_unique(
_req: Request,
Expand Down
1 change: 1 addition & 0 deletions test/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ macro_rules! add_routes (
add_route!($obj, get, "/socket/read", socket::handle_socket_read);
add_route!($obj, get, "/durable/auto-response", auto_response::handle_auto_response);
add_route!($obj, get, "/durable/hello", durable::handle_hello);
add_route!($obj, get, "/durable/ctor-name", durable::handle_ctor_name);
add_route!($obj, get, "/durable/hello-unique", durable::handle_hello_unique);
add_route!($obj, get, "/durable/storage", durable::handle_storage);
add_route!($obj, get, "/durable/handle-basic-test", durable::handle_basic_test);
Expand Down
9 changes: 9 additions & 0 deletions test/tests/durable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ describe("durable", () => {
expect(text).toBe("Hello from my-durable-object!");
});

// The name should be available in the constructor, before any request is
// handled (see https://github.com/cloudflare/workerd/issues/2240).
test("id-from-name preserves name on state.id() in constructor", async () => {
const resp = await mf.dispatchFetch(`${mfUrl}durable/ctor-name`);
expect(resp.status).toBe(200);
const text = await resp.text();
expect(text).toBe("Hello from my-durable-object!");
});

// unique_id() DOs should not have a name on state.id().
test("unique-id has no name on state.id()", async () => {
const resp = await mf.dispatchFetch(`${mfUrl}durable/hello-unique`);
Expand Down
12 changes: 10 additions & 2 deletions worker/src/durable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,16 @@ impl ObjectId<'_> {
}

/// The name that was used to create the `ObjectId` via [`id_from_name`](https://developers.cloudflare.com/durable-objects/api/namespace/#idfromname).
/// `None` is returned if the `ObjectId` was constructed using [`unique_id`](https://developers.cloudflare.com/durable-objects/api/namespace/#newuniqueid).
/// `None` is also returned within the Durable Object constructor, as the `name` property is not accessible there (see <https://github.com/cloudflare/workerd/issues/2240>).
///
/// When a Durable Object is addressed by name, the name is also passed
/// through to the object itself and is available via `state.id().name()`,
/// including inside the constructor and [`alarm`](crate::DurableObject::alarm)
/// handlers (see <https://github.com/cloudflare/workerd/issues/2240>).
///
/// `None` is returned in some cases, for example when the `ObjectId` was
/// constructed via [`unique_id`](https://developers.cloudflare.com/durable-objects/api/namespace/#newuniqueid).
/// See the [Durable Object ID docs](https://developers.cloudflare.com/durable-objects/api/id/#name)
/// for the full list of cases.
pub fn name(&self) -> Option<String> {
self.inner.name()
}
Expand Down
Loading