Skip to content

fix(wasm): relax networking traits Send+Sync via MaybeSendSync - #795

Merged
jlucaso1 merged 1 commit into
mainfrom
portability/relax-send-sync-net-store-wasm
Jun 9, 2026
Merged

fix(wasm): relax networking traits Send+Sync via MaybeSendSync#795
jlucaso1 merged 1 commit into
mainfrom
portability/relax-send-sync-net-store-wasm

Conversation

@jlucaso1

@jlucaso1 jlucaso1 commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

What

The three networking traits in wacore/src/net.rs (Transport, TransportFactory, HttpClient) hardcoded a Send + Sync supertrait, forcing a wasm32 transport/HTTP implementation to be Send + Sync even though the client is intentionally !Send there and a browser WebSocket/fetch backend holds !Send JS handles.

This mirrors the established convention (EventHandler, SendContextResolver, and the recently-merged EncHandler in #793): the supertrait becomes crate::sync_marker::MaybeSendSync, which is Send + Sync on native and no bound on wasm32. The async_trait(?Send) gates already existed and are now consistent with the relaxed supertrait.

Why

Unblocks !Send-handle-backed transport/HTTP implementations on the wasm port.

Native impact

None. The blanket MaybeSendSync impl keeps dyn Transport/dyn HttpClient Send + Sync on native, so the Arc<dyn Transport> / Arc<dyn HttpClient> cross-thread storage is unchanged.

Scope note

This intentionally does not include the sibling store/Backend traits (portability-05). I tried it and that relaxation cascades into 128 errors: impl_store_wrapper and the Device hold Arc<dyn Backend> and require it to be Send + Sync, so relaxing the store traits needs the wrapper macro and Device made wasm-aware too. That is a separate, larger change, not a one-line supertrait swap.

Verification

Native build + cargo clippy --all-targets -- -D warnings clean, and the wasm32 lib build (cargo build -p whatsapp-rust --lib --release --target wasm32-unknown-unknown --no-default-features --features debug-diagnostics) passes.

…MaybeSendSync

The three networking traits in wacore/src/net.rs hardcoded a Send + Sync
supertrait, forcing a wasm32 transport/HTTP implementation to be Send + Sync even
though the client is intentionally !Send there and a browser WebSocket/fetch
backend holds !Send JS handles.

Mirror the established convention (EventHandler, SendContextResolver, EncHandler):
supertrait becomes crate::sync_marker::MaybeSendSync, which is Send + Sync on
native (the blanket impl keeps Arc<dyn Transport>/Arc<dyn HttpClient> cross-thread
storage unchanged) and no bound on wasm32. The async_trait(?Send) gates already
existed and are now consistent with the relaxed supertrait.

Verified native build/clippy and the wasm32 lib build.

Note: the sibling store/Backend traits (portability-05) are NOT included here. That
relaxation cascades into 128 errors because impl_store_wrapper and the Device hold
Arc<dyn Backend> and require it to be Send + Sync; relaxing those needs the wrapper
macro and Device made wasm-aware too, which is a separate, larger change.
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 76c4c793-a181-4b04-be97-6ed3683bb1d9

📥 Commits

Reviewing files that changed from the base of the PR and between b61b1df and b015433.

📒 Files selected for processing (1)
  • wacore/src/net.rs

📝 Walkthrough

Summary by CodeRabbit

  • Refactor
    • Enhanced internal synchronization framework for improved platform compatibility across different runtime environments and compilation targets. Updated core trait implementations to provide better flexibility and support for diverse deployment scenarios. All existing functionality and public API contracts remain fully compatible and unchanged.

Walkthrough

Three networking traits in wacore/src/net.rsTransport, TransportFactory, and HttpClient—now use the MaybeSendSync marker bound instead of requiring Send + Sync directly. This conditional bound enables WASM targets to relax thread-safety constraints where necessary while maintaining full synchronization requirements on standard platforms.

Changes

Networking trait sync bound relaxation

Layer / File(s) Summary
Sync bound relaxation for networking traits
wacore/src/net.rs
Transport, TransportFactory, and HttpClient traits now use crate::sync_marker::MaybeSendSync instead of explicit Send + Sync bounds. This allows the traits to work with non-Send types on WASM targets while preserving full thread-safety guarantees on standard platforms.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

  • oxidezap/whatsapp-rust#671: Introduces and adopts the wacore::sync_marker::MaybeSendSync pattern; this PR extends it to the networking traits.
  • oxidezap/whatsapp-rust#793: Applies the same MaybeSendSync bound relaxation pattern to other async extension traits for WASM compatibility.
  • oxidezap/whatsapp-rust#476: Previously modified HttpClient trait with feature additions; this PR updates its synchronization bounds.

Suggested labels

api-design

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: relaxing Send+Sync bounds on networking traits via MaybeSendSync for wasm compatibility.
Description check ✅ Passed The description is directly related to the changeset, providing clear context on what was changed, why, and its impact on both native and wasm platforms.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch portability/relax-send-sync-net-store-wasm

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jlucaso1
jlucaso1 merged commit 208d04f into main Jun 9, 2026
11 checks passed
@jlucaso1
jlucaso1 deleted the portability/relax-send-sync-net-store-wasm branch June 9, 2026 13:40
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

Benchmark Results

67 unchanged benchmark(s)
Benchmark Current Baseline Change
reporting_token_benchmark::content_extraction_group::bench_content_extraction simple:setup_simple_message() 2,927 2,927 +0.0%
reporting_token_benchmark::content_extraction_group::bench_content_extraction extended:setup_extended_message() 8,448 8,448 +0.0%
reporting_token_benchmark::key_derivation_group::bench_key_derivation 31,317 31,317 +0.0%
reporting_token_benchmark::token_calculation_group::bench_token_calculation 13,827 13,827 +0.0%
reporting_token_benchmark::full_generation_group::bench_full_token_generation simple:setup_full_gen_simple() 49,487 49,487 +0.0%
reporting_token_benchmark::full_generation_group::bench_full_token_generation extended:setup_full_gen_extended() 55,003 55,003 +0.0%
reporting_token_benchmark::message_encoding_group::bench_message_encoding simple:setup_simple_message() 1,679 1,679 +0.0%
reporting_token_benchmark::message_encoding_group::bench_message_encoding extended:setup_extended_message() 4,393 4,393 +0.0%
send_receive_benchmark::dm_send::bench_dm_send text:setup_dm_send() 113,055 113,208 -0.1%
send_receive_benchmark::dm_recv::bench_dm_recv text:setup_dm_recv() 1,656,734 1,656,733 +0.0%
send_receive_benchmark::group_send::bench_group_send group_10:setup_group_send_10() 644,445 644,472 -0.0%
send_receive_benchmark::group_send::bench_group_send group_50:setup_group_send_50() 868,536 868,512 +0.0%
send_receive_benchmark::group_send::bench_group_send group_256:setup_group_send_256() 2,076,242 2,076,231 +0.0%
send_receive_benchmark::group_send_skdm::bench_group_send_skdm skdm_10:setup_group_skdm_10() 741,658 741,849 -0.0%
send_receive_benchmark::group_send_skdm::bench_group_send_skdm skdm_50:setup_group_skdm_50() 1,323,073 1,323,128 -0.0%
send_receive_benchmark::group_send_skdm::bench_group_send_skdm skdm_256:setup_group_skdm_256() 4,379,218 4,363,697 +0.4%
send_receive_benchmark::group_recv::bench_group_recv text:setup_group_recv() 516,993 512,124 +1.0%
binary_benchmark::marshal_group::bench_marshal_allocating 45,381 45,381 +0.0%
binary_benchmark::marshal_group::bench_marshal_auto_allocating 45,431 45,431 +0.0%
binary_benchmark::marshal_group::bench_marshal_exact_allocating 66,334 66,334 +0.0%
binary_benchmark::marshal_group::bench_marshal_reusing_buffer 43,492 43,492 +0.0%
binary_benchmark::marshal_group::bench_marshal_reusing_buffer_vec_writer 45,487 45,487 +0.0%
binary_benchmark::marshal_group::bench_marshal_long_string 4,945 4,945 +0.0%
binary_benchmark::marshal_group::bench_marshal_auto_long_string 4,976 4,976 +0.0%
binary_benchmark::marshal_group::bench_marshal_exact_long_string 6,747 6,747 +0.0%
binary_benchmark::marshal_group::bench_marshal_huge_bytes_allocating 528,544 528,544 +0.0%
binary_benchmark::marshal_group::bench_marshal_auto_huge_bytes_allocating 528,165 528,165 +0.0%
binary_benchmark::marshal_group::bench_marshal_exact_huge_bytes_allocating 529,411 529,411 +0.0%
binary_benchmark::marshal_group::bench_marshal_many_children_allocating 5,417,732 5,417,732 +0.0%
binary_benchmark::marshal_group::bench_marshal_auto_many_children_allocating 5,362,047 5,362,047 +0.0%
binary_benchmark::marshal_group::bench_marshal_exact_many_children_allocating 13,276,365 13,276,365 +0.0%
binary_benchmark::unmarshal_group::bench_unmarshal small:setup_small_marshaled() 1,850 1,850 +0.0%
binary_benchmark::unmarshal_group::bench_unmarshal large:setup_large_marshaled() 29,217 29,217 +0.0%
binary_benchmark::unpack_group::bench_unpack_uncompressed 618 618 +0.0%
binary_benchmark::unpack_group::bench_unpack_compressed 672,890 672,890 +0.0%
binary_benchmark::attr_parser_group::bench_attr_parser attr_lookup:setup_attr_marshaled() 3,736 3,736 +0.0%
binary_benchmark::roundtrip_group::bench_roundtrip small:setup_small_marshaled() 3,840 3,840 +0.0%
binary_benchmark::roundtrip_group::bench_roundtrip large:setup_large_marshaled() 48,274 48,274 +0.0%
binary_benchmark::roundtrip_group::bench_roundtrip_auto small:setup_small_marshaled() 3,866 3,866 +0.0%
binary_benchmark::roundtrip_group::bench_roundtrip_auto large:setup_large_marshaled() 48,335 48,335 +0.0%
binary_benchmark::roundtrip_group::bench_roundtrip_exact small:setup_small_marshaled() 5,206 5,206 +0.0%
binary_benchmark::roundtrip_group::bench_roundtrip_exact large:setup_large_marshaled() 66,659 66,659 +0.0%
binary_benchmark::child_iteration_group::bench_get_children_by_tag 310,312 310,312 +0.0%
binary_benchmark::jid_optimization_group::bench_jid_to_owned_access jid_access:setup_jid_heavy_marshaled() 8,291 8,291 +0.0%
numeric_attr_benchmark::bench_group::bench_baseline_u32 254 254 +0.0%
numeric_attr_benchmark::bench_group::bench_proposed_u32 91 91 +0.0%
numeric_attr_benchmark::bench_group::bench_baseline_u64 292 292 +0.0%
numeric_attr_benchmark::bench_group::bench_proposed_u64 137 137 +0.0%
numeric_attr_benchmark::bench_group::bench_baseline_i64 317 317 +0.0%
numeric_attr_benchmark::bench_group::bench_proposed_i64 145 145 +0.0%
numeric_attr_benchmark::bench_group::bench_baseline_loop_100_u64 27,425 27,425 +0.0%
numeric_attr_benchmark::bench_group::bench_proposed_loop_100_u64 10,725 10,725 +0.0%
libsignal_benchmark::dm_group::bench_dm_session_establishment setup:setup_dm_users() 4,142,669 4,142,867 -0.0%
libsignal_benchmark::dm_group::bench_dm_encrypt_first_message first_msg:setup_dm_session() 100,133 100,133 +0.0%
libsignal_benchmark::dm_group::bench_dm_decrypt_first_message decrypt_prekey:setup_dm_with_first_message() 4,264,189 4,264,189 +0.0%
libsignal_benchmark::dm_group::bench_dm_encrypt_subsequent_message subsequent:setup_established_dm_session() 100,399 100,399 +0.0%
libsignal_benchmark::group_messaging_group::bench_group_create_distribution_message create:setup_group_sender() 210,262 210,262 +0.0%
libsignal_benchmark::group_messaging_group::bench_group_encrypt_message encrypt:setup_group_with_distribution() 496,921 496,921 +0.0%
libsignal_benchmark::group_messaging_group::bench_group_decrypt_message decrypt:setup_group_with_encrypted_message() 507,577 505,496 +0.4%
libsignal_benchmark::conversation_group::bench_full_dm_conversation full:setup_conversation_data() 11,978,287 11,978,878 -0.0%
libsignal_benchmark::signature_group::bench_signature_creation sign:setup_keypair_with_message() 2,466,138 2,466,138 +0.0%
libsignal_benchmark::signature_group::bench_signature_verification verify:setup_keypair_with_message() 4,913,342 4,921,562 -0.2%
libsignal_benchmark::signature_group::bench_key_generation keygen 2,043,397 2,043,397 +0.0%
libsignal_benchmark::session_optimization_group::bench_decrypt_with_previous_session previous_session:setup_with_archived_sessions() 37,414 37,404 +0.0%
libsignal_benchmark::session_optimization_group::bench_out_of_order_decryption out_of_order:setup_out_of_order_messages() 3,617,967 3,617,967 +0.0%
libsignal_benchmark::session_optimization_group::bench_promote_matching_session promote:setup_promote_matching_session() 230,638 230,648 -0.0%
libsignal_benchmark::session_optimization_group::bench_message_key_eviction eviction:setup_message_key_eviction() 9,980,959 9,980,959 +0.0%
No significant changes detected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant