Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[refactor] Switch from Rc<T> to Arc<T> #366

Merged
merged 1 commit into from
Nov 7, 2023

Conversation

fabricedesre
Copy link
Collaborator

@fabricedesre fabricedesre commented Nov 2, 2023

Summary

This PR fixes/implements the following bugs/features

Closing issues

closes #250

After Merge

  • Does this change invalidate any docs or tutorials? If so ensure the changes needed are either made or recorded
  • Does this change require a release to be made? Is so please create and deploy the release

I didn't bump the crate version number yet. This change is breaking the API backward compatibility so that should be a major semver change, but I'll let you decide what you want to do about it.

@fabricedesre fabricedesre requested a review from a team as a code owner November 2, 2023 18:12
Copy link

codecov bot commented Nov 2, 2023

Codecov Report

Merging #366 (35922c6) into main (6df4a6b) will decrease coverage by 0.14%.
The diff coverage is 72.14%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #366      +/-   ##
==========================================
- Coverage   56.84%   56.70%   -0.14%     
==========================================
  Files          45       45              
  Lines        3339     3333       -6     
  Branches      832      832              
==========================================
- Hits         1898     1890       -8     
- Misses        884      886       +2     
  Partials      557      557              
Files Coverage Δ
wnfs-common/src/async_serialize.rs 33.33% <ø> (ø)
wnfs-common/src/link.rs 19.76% <ø> (ø)
wnfs-hamt/src/pointer.rs 21.87% <ø> (ø)
wnfs/src/private/link.rs 54.43% <100.00%> (ø)
wnfs/src/private/share.rs 65.62% <ø> (ø)
wnfs/src/public/link.rs 53.84% <100.00%> (ø)
wnfs/src/root_tree.rs 61.84% <100.00%> (ø)
wnfs/src/utils/test.rs 72.88% <100.00%> (ø)
wnfs-hamt/src/hamt.rs 41.02% <75.00%> (ø)
wnfs/src/public/file.rs 76.27% <85.71%> (ø)
... and 10 more

... and 3 files with indirect coverage changes

@matheus23
Copy link
Member

I didn't bump the crate version number yet. This change is breaking the API backward compatibility so that should be a major semver change, but I'll let you decide what you want to do about it.

Yeah we're super not doing semver yet, but that's fine if that's another PR.


Seems like the wasm code needs the same Rc -> Arc treatment, but I think that should be fine. IIUC, Arc in wasm32-unknown-unknown ends up being identical to Rc in functionality (which is a bummer). But it should compile.

Copy link
Member

@matheus23 matheus23 left a comment

Choose a reason for hiding this comment

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

Relief GIF

Thank you for doing this laborious work!

@matheus23 matheus23 merged commit 30ed01b into wnfs-wg:main Nov 7, 2023
10 checks passed
matheus23 added a commit that referenced this pull request Nov 28, 2023
The main goal of this PR is to enable using rs-wnfs in multithreaded contexts, e.g. in axum webservers.
We have a test repo to check whether that works in an MVP: https://github.com/fabricedesre/wnfs-mtload/

Previously that wasn't possible, since the async futures from rs-wnfs weren't `Send`, so you couldn't have a multi-threaded work-stealing async runtime work on them.
The reasons they weren't sync were:
- Futures would capture an `impl BlockStore`, and it's not necessarily known to be `Send`
- Futures would capture an `impl PrivateForest` with the same problem
- Some functions would produce `LocalBoxFuture` or `LocalBoxStream`, which aren't `Send`
- We'd use `async_trait(?Send)` and `async_recursion(?Send)` which opt-in to not having `Send` bounds, since that's what we need for wasm
- Futures would capture internal WNFS data structures like `PrivateNode`, which would use `Rc` internally instead of `Arc`, see also #250 

Some of this work was already addressed in #366. This PR *should* cover the rest.

---

There's a complication with Wasm, where we're e.g. using an external type `extern "C" { type BlockStore; ... }`, which isn't `Send` or `Sync`, and as such can't ever implement a `trait BlockStore: Send + Sync`.
To fix this, we're conditionally compiling in `Send` and `Sync` bounds (and `Arc` and `Rc` and similar) based on the target (See `send_sync_poly.rs`). This is pretty much just copying what noosphere is doing: https://github.com/subconsciousnetwork/noosphere/blob/main/rust/noosphere-common/src/sync.rs

I'm hoping eventually we just fix this and thus enable multi-threaded Wasm, too. But for now this works.

---

* wip - still need to fix the SnapshotBlockStore implementation

* Fix SnapshotBlockStore impl

* Fix wnfs=hamt

* fix: `Send` bounds & `BytesToIpld` implementations

Also: fix formatting

* feat: Also make `PrivateForest` trait `Send + Sync`

Also: Remove unneeded `Sync` bounds left over from previous commits.

* feat: Use `BoxFuture` instead of `LocalBoxFuture` in `PrivateForest` fn

* feat: Remove `(?Send)` annotations everywhere

* feat: Conditionally compile `Send + Sync` bounds

This relaxes the requirement if you're not on the `wasm32` target.
The problem is that foreign types in Wasm don't implement `Sync`.

* chore: Fix all tests & doctests to use thread-safe RNGs

---------

Co-authored-by: Fabrice Desré <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor: Consider switching from Rc to Arc
2 participants