Skip to content
This repository has been archived by the owner on Sep 3, 2021. It is now read-only.

Very beginning of IdbStore #1

Merged
merged 1 commit into from
Jun 13, 2020
Merged

Very beginning of IdbStore #1

merged 1 commit into from
Jun 13, 2020

Conversation

aboodman
Copy link
Contributor

Not for landing yet.

@aboodman
Copy link
Contributor Author

Amazingly, this prints out:

console.log div contained:
    request: IdbOpenDbRequest { obj: IdbRequest { obj: EventTarget { obj: Object { obj: JsValue(IDBOpenDBRequest) } } } }

src/idbstore.rs Outdated
log!("request: {:?}", request);

let (sender, receiver) = oneshot::channel::<()>();
let success = Closure::wrap(Box::new(move || {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails here, with:

repc!? cargo build
   Compiling replicache-client v0.1.0 (/Users/aa/work/roci/repc)
error[E0277]: expected a `std::ops::Fn<()>` closure, found `[closure@src/idbstore.rs:21:46: 24:10 sender:futures_channel::oneshot::Sender<()>]`
  --> src/idbstore.rs:21:37
   |
21 |           let success = Closure::wrap(Box::new(move || {
   |  _____________________________________^
22 | |             log!("onsuccess called!!1!");
23 | |             sender.send(());
24 | |         }) as Box<dyn Fn()>);
   | |__________^ expected an `Fn<()>` closure, found `[closure@src/idbstore.rs:21:46: 24:10 sender:futures_channel::oneshot::Sender<()>]`
   |
   = help: the trait `std::ops::Fn<()>` is not implemented for `[closure@src/idbstore.rs:21:46: 24:10 sender:futures_channel::oneshot::Sender<()>]`
   = note: wrap the `[closure@src/idbstore.rs:21:46: 24:10 sender:futures_channel::oneshot::Sender<()>]` in a closure with no arguments: `|| { /* code */ }
   = note: required for the cast to the object type `dyn std::ops::Fn()`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `replicache-client`.

To learn more, run the command again with --verbose.

From some research it appears that the error message is bad, and actual problem is that my closure is FnOnce: rustwasm/wasm-bindgen#1269.

However, attempting to wrap sender in an option and taking it inside the closure doesn't help.

@sayrer
Copy link
Contributor

sayrer commented Jun 11, 2020

Change the name arguments to String (rather than references, so the async fn can take ownership). [edit, actually only newReplicache needs to be String]

#[wasm_bindgen]
pub async fn newReplicache(name: String) {
    #[cfg(feature = "console_error_panic_hook")]
    console_error_panic_hook::set_once();

    IdbStore::new(&name).await;
}

@sayrer
Copy link
Contributor

sayrer commented Jun 11, 2020

You can see the macro expansion like this:

cargo rustc --profile=check -- -Zunstable-options --pretty=expanded

@sayrer
Copy link
Contributor

sayrer commented Jun 11, 2020

I tried this too: https://rust-lang.github.io/async-book/03_async_await/01_chapter.html#async-lifetimes

But that gets you:
error: can't #[wasm_bindgen] functions with lifetime or type parameters

I haven't played with this stuff that much, so this is interesting to look at.

@aboodman
Copy link
Contributor Author

aboodman commented Jun 13, 2020

Change the name arguments to String (rather than references, so the async fn can take ownership). [edit, actually only newReplicache needs to be String]

OK that solved it. I'm having a heck of a time parsing https://rust-lang.github.io/async-book/03_async_await/01_chapter.html#async-lifetimes, but the reason that ownership needs to be passed here make sense:

Callers don't have to await an async function. They are allowed to call it and do something else with the returned future. In that case, the lifetime of params passed by ref might not be long enough.

(also looping back to C++ -- a lot of working with Rust feels so similar to patterns and idimos that were encouraged in Chrome's C++ -- this is exactly what you'd have to do to pass a string to a c++ closure or something. You'd have to pass it by value, not const&.)

Thanks!

> wasm-pack test --headless --chrome
...
running 1 test                                    

test wasm::test_new ... ok

test result: ok. 1 passed; 0 failed; 0 ignored

console.log div contained:
    onsuccess called!!1!

replicache_client.js: 10010
replicache_client.js.br: 2460
replicache_client_bg.wasm: 14309
replicache_client_bg.wasm.br: 6284
@aboodman
Copy link
Contributor Author

Huh. For some reason the wasm got smaller, but the js goop got a lot larger. The latter makes sense because of the addition of Futures to the wasm API.

I feel like given what we're trying to do, we might not even want wasm-bindgen. We're just trying to pass buffers around. But I don't feel like investigating that now, so I'm going to keep doing it this way and maybe circle back later.

@aboodman aboodman merged commit fcfea9f into master Jun 13, 2020
@sayrer
Copy link
Contributor

sayrer commented Jun 13, 2020

The lifetime annotations are (roughly) a way to indicate that the input lifetime must equal or exceed the output lifetime. If a function reallocates to create its output, then these are not needed.

But, if you're trying to write something that returns a slice from a Vec without reallocating, you can do this with lifetime parameters.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants