workers-rs icon indicating copy to clipboard operation
workers-rs copied to clipboard

Make Durable Objects support DECENT

Open kanarus opened this issue 1 year ago • 1 comments

Problem

Currently, this crate's support for Durable Objects works, but its developer experience is incredibly bad:

use worker::{durable_object, DurableObject};
// 1. We MUST introduce them into the scope for this code to compile.
use worker::{async_trait, wasm_bindgen};

#[durable_object]
struct MyObject {
    state: worker::State,
}

// 2. This attribute to impl-block prevents editor's completions of trait methods.
// 3. And this uses `async_trait` which is unnecessary, bothering layer now.
#[durable_object]
// 4. Due to current implementation of the attribute, hover and code jump on
// this ↓ `DurableObject` doesn't work.
impl DurableObject for MyObject {
    //...
}

// 5. Defining multiple Durable Objects causes compile error due to the wrong design of Durable Objects support
#[durable_object]
struct AnotherObject;

#[durable_object]
impl DurableObject for AnotherObject { /* ... */ }
Details with Pictures
  • 5 is reported in #432

  • 1 makes error messages difficult to understand for those who avoid use worker::*;:

    • worker exports a lot of items from the top-level, so *-import causes serious namespace pollution and many developer will like to avoid it

Screenshot from 2024-11-28 16-19-53

  • 3 leads to very unfriendly error messages for unexpected usage like:

Screenshot from 2024-11-28 16-07-45

  • 2, 4: completion or hover doesn't work:

Screenshot from 2024-11-28 16-25-45

Solution

This PR resolves all of them by re-designing Durable Objects support. See worker-macros/src/durable_object.rs for how new #[DurableObject] works internally.

usage:

// 1. We only have to import `DurableObject`.
use worker::DurableObject;

#[DurableObject]
struct MyObject {
    state: worker::State,
}

// 2,3,4. Now we don't need annoying attribute on impl-block.
// Of course, hover and code jump and completion works perfectly.
impl DurableObject for MyObject {
    //...
}

// 5. This compiles. No problem.
#[DurableObject]
pub struct AnotherObject;

impl DurableObject for AnotherObject {
    //...
}
Details with Pictures
  • ( 1, 2, 3, 4 ) Of course, completion, hover and code jump work perfectly

Screenshot from 2024-11-28 16-02-37

Screenshot from 2024-11-28 16-12-55

Screenshot from 2024-11-28 16-39-13

  • ( 5 ) More than one Durable Objects don't cause problem ( so closes #432 ).

Screenshot from 2024-11-28 16-11-47

  • Very clear error message for unexpected usage:

if attribute is missing: Screenshot from 2024-11-28 16-01-16

if trait impl is missing: Screenshot from 2024-11-28 16-01-58

Additionally, even if we merge this PR immediately, current codes still compile and work, just with "deprecated" warnings, due to some effort for backward compatibility:

Screenshot from 2024-11-28 16-44-14

kanarus avatar Nov 28 '24 08:11 kanarus

I also ran into the multiple durable objects problem, would be great if this can get merged o7

adhami3310 avatar Dec 10 '24 18:12 adhami3310

This is fantastic, thanks for working on it.

I've gone ahead and pushed up a rebase here and also update it to be a breaking change with a clear compile error if the impl attribute is not removed.

Further feedback welcome, otherwise I will aim to go ahead and get this one release with the 0.6 update.

guybedford avatar Jun 18 '25 23:06 guybedford