Skip to content
Merged
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
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

132 changes: 70 additions & 62 deletions worker-macros/src/durable_object.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions worker-sandbox/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ chrono = { version = "0.4", default-features = false, features = [
cfg-if = "1.0"
console_error_panic_hook = { version = "0.1.7", optional = true }
getrandom = { version = "0.3", features = ["wasm_js"] }
gloo-timers = { version = "0.3.0", features = ["futures"] }
hex = "0.4"
http.workspace = true
regex = "1.8.4"
Expand Down
22 changes: 16 additions & 6 deletions worker-sandbox/src/alarm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl DurableObject for AlarmObject {
Self { state }
}

async fn fetch(&mut self, _: Request) -> Result<Response> {
async fn fetch(&self, _: Request) -> Result<Response> {
let alarmed: bool = match self.state.storage().get("alarmed").await {
Ok(alarmed) => alarmed,
Err(e) if e.to_string() == "No such value in storage." => {
Expand All @@ -34,7 +34,7 @@ impl DurableObject for AlarmObject {
Response::ok(alarmed.to_string())
}

async fn alarm(&mut self) -> Result<Response> {
async fn alarm(&self) -> Result<Response> {
self.state.storage().put("alarmed", true).await?;

console_log!("Alarm has been triggered!");
Expand All @@ -54,8 +54,13 @@ pub async fn handle_alarm(_req: Request, env: Env, _data: SomeSharedData) -> Res
}

#[worker::send]
pub async fn handle_id(_req: Request, env: Env, _data: SomeSharedData) -> Result<Response> {
let namespace = env.durable_object("COUNTER").expect("DAWJKHDAD");
pub async fn handle_id(req: Request, env: Env, _data: SomeSharedData) -> Result<Response> {
let durable_object_name = if req.path().contains("shared") {
"SHARED_COUNTER"
} else {
"COUNTER"
};
let namespace = env.durable_object(durable_object_name).expect("DAWJKHDAD");
let stub = namespace.id_from_name("A")?.get_stub()?;
// when calling fetch to a Durable Object, a full URL must be used. Alternatively, a
// compatibility flag can be provided in wrangler.toml to opt-in to older behavior:
Expand All @@ -72,15 +77,20 @@ pub async fn handle_put_raw(req: Request, env: Env, _data: SomeSharedData) -> Re
}

#[worker::send]
pub async fn handle_websocket(_req: Request, env: Env, _data: SomeSharedData) -> Result<Response> {
pub async fn handle_websocket(req: Request, env: Env, _data: SomeSharedData) -> Result<Response> {
let durable_object_name = if req.path().contains("shared") {
"SHARED_COUNTER"
} else {
"COUNTER"
};
// Accept / handle a websocket connection
let pair = WebSocketPair::new()?;
let server = pair.server;
server.accept()?;

// Connect to Durable Object via WS
let namespace = env
.durable_object("COUNTER")
.durable_object(durable_object_name)
.expect("failed to get namespace");
let stub = namespace.id_from_name("A")?.get_stub()?;
let mut req = Request::new("https://fake-host/ws", Method::Get)?;
Expand Down
31 changes: 17 additions & 14 deletions worker-sandbox/src/counter.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
use std::cell::RefCell;

use worker::*;

#[durable_object]
pub struct Counter {
count: usize,
count: RefCell<usize>,
state: State,
initialized: bool,
initialized: RefCell<bool>,
env: Env,
}

#[durable_object]
impl DurableObject for Counter {
fn new(state: State, env: Env) -> Self {
Self {
count: 0,
initialized: false,
count: RefCell::new(0),
initialized: RefCell::new(false),
state,
env,
}
}

async fn fetch(&mut self, req: Request) -> Result<Response> {
if !self.initialized {
self.initialized = true;
self.count = self.state.storage().get("count").await.unwrap_or(0);
async fn fetch(&self, req: Request) -> Result<Response> {
if !*self.initialized.borrow() {
*self.initialized.borrow_mut() = true;
*self.count.borrow_mut() = self.state.storage().get("count").await.unwrap_or(0);
}

if req.path().eq("/ws") {
Expand All @@ -40,18 +42,19 @@ impl DurableObject for Counter {
.empty());
}

self.count += 10;
self.state.storage().put("count", self.count).await?;
*self.count.borrow_mut() += 10;
let count = *self.count.borrow();
self.state.storage().put("count", count).await?;

Response::ok(format!(
"[durable_object]: self.count: {}, secret value: {}",
self.count,
self.count.borrow(),
self.env.secret("SOME_SECRET")?
))
}

async fn websocket_message(
&mut self,
&self,
ws: WebSocket,
_message: WebSocketIncomingMessage,
) -> Result<()> {
Expand All @@ -69,7 +72,7 @@ impl DurableObject for Counter {
}

async fn websocket_close(
&mut self,
&self,
_ws: WebSocket,
_code: usize,
_reason: String,
Expand All @@ -78,7 +81,7 @@ impl DurableObject for Counter {
Ok(())
}

async fn websocket_error(&mut self, _ws: WebSocket, _error: Error) -> Result<()> {
async fn websocket_error(&self, _ws: WebSocket, _error: Error) -> Result<()> {
Ok(())
}
}
20 changes: 12 additions & 8 deletions worker-sandbox/src/test/export_durable_object.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use serde::Serialize;
use std::collections::HashMap;
use std::{cell::RefCell, collections::HashMap};

use worker::{js_sys::Uint8Array, wasm_bindgen::JsValue, *};

Expand All @@ -8,21 +8,24 @@ use crate::ensure;
#[durable_object]
pub struct MyClass {
state: State,
number: usize,
number: RefCell<usize>,
}

#[durable_object]
impl DurableObject for MyClass {
fn new(state: State, _env: Env) -> Self {
Self { state, number: 0 }
Self {
state,
number: RefCell::new(0),
}
}

async fn fetch(&mut self, req: Request) -> Result<Response> {
async fn fetch(&self, req: Request) -> Result<Response> {
let handler = async move {
match req.path().as_str() {
"/hello" => Response::ok("Hello!"),
"/storage" => {
let mut storage = self.state.storage();
let storage = self.state.storage();
let map = [("one".to_string(), 1), ("two".to_string(), 2)]
.iter()
.cloned()
Expand Down Expand Up @@ -116,12 +119,13 @@ impl DurableObject for MyClass {
);
}

self.number = storage.get("count").await.unwrap_or(0) + 1;
*self.number.borrow_mut() = storage.get("count").await.unwrap_or(0) + 1;

storage.delete_all().await?;

storage.put("count", self.number).await?;
Response::ok(self.number.to_string())
let count = *self.number.borrow();
storage.put("count", count).await?;
Response::ok(self.number.borrow().to_string())
}
"/transaction" => {
Response::error("transactional storage API is still unstable", 501)
Expand Down
10 changes: 5 additions & 5 deletions worker-sandbox/src/test/put_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ pub struct PutRawTestObject {
}

impl PutRawTestObject {
async fn put_raw(&mut self) -> Result<()> {
let mut storage = self.state.storage();
async fn put_raw(&self) -> Result<()> {
let storage = self.state.storage();
let bytes = Uint8Array::new_with_length(3);
bytes.copy_from(b"123");
storage.put_raw("bytes", bytes).await?;
Expand All @@ -20,8 +20,8 @@ impl PutRawTestObject {
Ok(())
}

async fn put_multiple_raw(&mut self) -> Result<()> {
let mut storage = self.state.storage();
async fn put_multiple_raw(&self) -> Result<()> {
let storage = self.state.storage();
let obj = js_sys::Object::new();
const BAR: &[u8] = b"bar";
let value = Uint8Array::new_with_length(BAR.len() as _);
Expand All @@ -45,7 +45,7 @@ impl DurableObject for PutRawTestObject {
Self { state }
}

async fn fetch(&mut self, _: Request) -> Result<Response> {
async fn fetch(&self, _: Request) -> Result<Response> {
self.put_raw().await?;
self.put_multiple_raw().await?;

Expand Down
1 change: 0 additions & 1 deletion worker-sandbox/tests/durable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,3 @@ describe("durable", () => {
expect(closeHandlerWrapper).toBeCalled();
});
});

1 change: 1 addition & 0 deletions worker-sandbox/tests/mf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const mf = new Miniflare({
},
durableObjects: {
COUNTER: "Counter",
SHARED_COUNTER: "SharedCounter",
PUT_RAW_TEST_OBJECT: "PutRawTestObject",
},
kvNamespaces: ["SOME_NAMESPACE", "FILE_SIZES", "TEST"],
Expand Down
1 change: 1 addition & 0 deletions worker-sandbox/wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ remote-service = "./remote-service"
[durable_objects]
bindings = [
{ name = "COUNTER", class_name = "Counter" },
{ name = "SHARED_COUNTER", class_name = "SharedCounter" },
{ name = "ALARM", class_name = "AlarmObject" },
{ name = "PUT_RAW_TEST_OBJECT", class_name = "PutRawTestObject" },
]
Expand Down
Loading