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

feat: a more lightweight approach #149

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
8478eb7
move all the things to old
rklaehn Mar 16, 2025
44a8840
new, more low level approach to rpc
rklaehn Mar 16, 2025
3bcdc86
Add first version of the macro crate
rklaehn Mar 16, 2025
1607a02
keep the first example macro free
rklaehn Mar 16, 2025
c28ae8b
WIP macros
rklaehn Mar 16, 2025
97d53a3
WIP macros
rklaehn Mar 16, 2025
37c1144
WIP rename
rklaehn Mar 16, 2025
09a77f1
works!
rklaehn Mar 16, 2025
7cd6c33
fix comments
rklaehn Mar 16, 2025
0bfac3c
one attribute
rklaehn Mar 16, 2025
7567a66
Add more tests and derive example
rklaehn Mar 16, 2025
2b55b7b
rename rpc feature
rklaehn Mar 16, 2025
36d0a81
Minimize deps even more
rklaehn Mar 16, 2025
206daba
enough for today
rklaehn Mar 16, 2025
9b74bec
Fix a dependency
rklaehn Mar 16, 2025
0006ac4
Add compute example
rklaehn Mar 16, 2025
b6ddade
WIP
rklaehn Mar 16, 2025
6bde683
adapt channel size to same value as in old quic-rpc bench
rklaehn Mar 16, 2025
02d7823
rename Msg to WithChannels again
rklaehn Mar 17, 2025
fada3c4
Add the weird stuff to get the feature flags in docs
rklaehn Mar 17, 2025
57ec9a3
Remove old stuff
rklaehn Mar 17, 2025
6b02fc8
Remove some stuff and do the wasm part in a different way
rklaehn Mar 17, 2025
bc25ba8
clippy
rklaehn Mar 17, 2025
aacb6db
disable compile fail tests for now - they have tiny stupid diffs depe…
rklaehn Mar 17, 2025
ce1abd2
try to fix minimal crates
rklaehn Mar 17, 2025
342c253
another minimal crates fix
rklaehn Mar 17, 2025
902277e
increase version number by a lot and fix postcard minimal version
rklaehn Mar 17, 2025
e282b19
fix tokio-util as well
rklaehn Mar 17, 2025
6965776
Don't require derive_more in the macro
rklaehn Mar 17, 2025
d6ecf83
fix features
rklaehn Mar 17, 2025
2f73a82
Fuse the damn oneshot receiver
rklaehn Mar 17, 2025
2250980
Add ability to send if not busy
rklaehn Mar 18, 2025
90195f7
comment
rklaehn Mar 18, 2025
1f6561d
fixes
rklaehn Mar 18, 2025
39b7172
Add generic enum for local/remote
rklaehn Mar 18, 2025
9fd3f35
fix mismatch with blobs
rklaehn Mar 18, 2025
30e28b8
add spans to compute example
rklaehn Mar 20, 2025
f6d5069
Pass though get_parent_span from the WithChannels impl
rklaehn Mar 20, 2025
ec252c0
pub duh!
rklaehn Mar 20, 2025
15249c2
skip the span when debugging
rklaehn Mar 20, 2025
34c4192
Add a way to find out if a sender is rpc
rklaehn Mar 20, 2025
170f57b
Nicer debug, and don't log at warn level for a normal application close
rklaehn Mar 20, 2025
cf8f4fd
fix bug in try_send
rklaehn Mar 20, 2025
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
296 changes: 0 additions & 296 deletions CHANGELOG.md

This file was deleted.

4,795 changes: 847 additions & 3,948 deletions Cargo.lock

Large diffs are not rendered by default.

120 changes: 42 additions & 78 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "quic-rpc"
version = "0.18.3"
version = "0.50.0"
edition = "2021"
authors = ["Rüdiger Klaehn <[email protected]>", "n0 team"]
keywords = ["api", "protocol", "network", "rpc"]
Expand All @@ -13,94 +13,58 @@ description = "A streaming rpc system based on quic"
rust-version = "1.76"

[dependencies]
bytes = { version = "1", optional = true }
flume = { version = "0.11", optional = true }
futures-lite = "2.3.0"
futures-sink = "0.3.30"
futures-util = { version = "0.3.30", features = ["sink"] }
hyper = { version = "0.14.16", features = ["full"], optional = true }
iroh = { version = "0.33", optional = true }
pin-project = "1"
quinn = { package = "iroh-quinn", version = "0.13", optional = true }
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", default-features = false, features = ["macros", "sync"] }
tokio-serde = { version = "0.9", features = [], optional = true }
tokio-util = { version = "0.7", features = ["rt"] }
postcard = { version = "1", features = ["use-std"], optional = true }
tracing = "0.1"
futures = { version = "0.3.30", optional = true }
anyhow = "1"
document-features = "0.2"
# for test-utils
rcgen = { version = "0.13", optional = true }
# for test-utils
rustls = { version = "0.23", default-features = false, features = ["ring"], optional = true }
# we require serde even in non-rpc mode
serde = { version = "1", default-features = false }
# just for the oneshot and mpsc queues
tokio = { version = "1.38", features = ["sync"], default-features = false }
# for PollSender (which for some reason is not available in the main tokio api)
tokio-util = { version = "0.7.14", default-features = false }

# Indirect dependencies, is needed to make the minimal crates versions work
slab = "0.4.9" # iroh-quinn
smallvec = "1.13.2"
time = "0.3.36" # serde
# used in the endpoint handler code when using rpc
tracing = { version = "0.1.41", optional = true }
# used to ser/de messages when using rpc
postcard = { version = "1.1.1", features = ["alloc", "use-std"], optional = true }
# currently only transport when using rpc
quinn = { version = "0.13.0", package = "iroh-quinn", optional = true }
# used as a buffer for serialization when using rpc
smallvec = { version = "1.14.0", features = ["write"], optional = true }
# used in the test utils to generate quinn endpoints
rustls = { version = "0.23.5", default-features = false, features = ["std"], optional = true }
# used in the test utils to generate quinn endpoints
rcgen = { version = "0.13.2", optional = true }
# used in the test utils to generate quinn endpoints
anyhow = { version = "1.0.66", optional = true }
# used in the benches
futures-buffered ={ version = "0.2.9", optional = true }

[dev-dependencies]
anyhow = "1"
async-stream = "0.3.3"
derive_more = { version = "1", features = ["from", "try_into", "display"] }
rand = "0.8"

serde = { version = "1", features = ["derive"] }
tracing-subscriber = { version = "0.3.19", features = ["fmt"] }
# used in the derive example. This must not be a main crate dep or else it will be circular!
quic-rpc-derive = { path = "quic-rpc-derive" }
# just convenient for the enum definitions
derive_more = { version = "2", features = ["from"] }
# we need full for example main etc.
tokio = { version = "1", features = ["full"] }
quinn = { package = "iroh-quinn", version = "0.13", features = ["ring"] }
rcgen = "0.13"
# formatting
thousands = "0.2.0"
tracing-subscriber = "0.3.16"
tempfile = "3.5.0"
proc-macro2 = "1.0.66"
futures-buffered = "0.2.4"
testresult = "0.4.1"
nested_enum_utils = "0.1.0"
tokio-util = { version = "0.7", features = ["rt"] }
# for AbortOnDropHandle
n0-future = { version = "0.1.2" }

[features]
## HTTP transport using the `hyper` crate
hyper-transport = ["dep:flume", "dep:hyper", "dep:postcard", "dep:bytes", "dep:tokio-serde", "tokio-util/codec"]
## QUIC transport using the `iroh-quinn` crate
quinn-transport = ["dep:flume", "dep:quinn", "dep:postcard", "dep:bytes", "dep:tokio-serde", "tokio-util/codec"]
## In memory transport using the `flume` crate
flume-transport = ["dep:flume"]
## p2p QUIC transport using the `iroh` crate
iroh-transport = ["dep:iroh", "dep:flume", "dep:postcard", "dep:tokio-serde", "tokio-util/codec"]
## Macros for creating request handlers
macros = []
## Utilities for testing
test-utils = ["dep:rcgen", "dep:rustls"]
## Default, includes the memory transport
default = ["flume-transport"]
# enable the remote transport
rpc = ["dep:quinn", "dep:postcard", "dep:smallvec", "dep:tracing", "tokio/io-util"]
# add test utilities
test = ["dep:rustls", "dep:rcgen", "dep:anyhow", "dep:futures-buffered"]
# pick up parent span when creating channel messages
message_spans = []
default = ["rpc", "test", "message_spans"]

[workspace]
members = ["quic-rpc-derive"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "quicrpc_docsrs"]

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ["cfg(quicrpc_docsrs)"] }

[[example]]
name = "errors"
required-features = ["flume-transport"]

[[example]]
name = "macro"
required-features = ["flume-transport", "macros"]

[[example]]
name = "store"
required-features = ["flume-transport", "macros"]

[[example]]
name = "modularize"
required-features = ["flume-transport"]

[workspace]
members = ["examples/split/types", "examples/split/server", "examples/split/client", "quic-rpc-derive"]

[patch.crates-io]
iroh = { git = "https://github.com/n0-computer/iroh.git", branch = "main" }
4 changes: 2 additions & 2 deletions DOCS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Building docs for this crate is a bit complex. There are lots of feature flags,
so we want feature flag markers in the docs, especially for the transports.
Building docs for this crate is a bit complex. There are some feature flags,
so we want feature flag markers in the docs.

There is an experimental cargo doc feature that adds feature flag markers. To
get those, run docs with this command line:
Expand Down
36 changes: 11 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ It is still a RPC system in the sense that interactions get initiated by the cli

### Transports

- memory transport with very low overhead. In particular, no ser/deser, currently using [flume]
- quic transport via the [quinn] crate
- transparent combination of the above
- memory transport with very low overhead. In particular, no ser/deser, currently using [tokio channels]
when using tokio channels, there is zero overhead compared to just manually including backchannels in messages
- quic transport via the [iroh-quinn] crate

### API

Expand Down Expand Up @@ -64,35 +64,21 @@ channel. For almost all interactions these messages itself will again contain
(oneshot or mpsc) channels for independent async communication between the
subsystems.

Quic-rpc with the mem channel does exactly the same thing, except that it hides
the details and allows you to specify a clean high level interaction protocol
in the rust type system.
Quic-rpc with the mem channel does exactly the same thing, except that it
distinguishes between the serializable protocol of a service and the full
messages of a service that include unserializable channels.

Instead of having a message that explicitly contains some data and the send side
of a oneshot or mpsc channel for the response, it creates a pair of flume
channels internally and sends one end of them to the server. This has some slight
overhead (2 flume channels vs. 1 oneshot channel) for a RPC interaction. But
for streaming interactions the overhead is negligible.
of a oneshot or mpsc channel for the response, it allows you to specify the
channel kind and message type of the channels in both directions.

For the case where you have a process boundary, the overhead is very low for
transports that already have a concept of cheap substreams (http2, quic, ...).
Quic is the poster child of a network transport that has built in cheap
substreams including per substream backpressure. However, I found that for raw
data transfer http2/tcp has still superior performance. This is why the http2
transport exists.
substreams including per substream backpressure.

Currently you would use the quinn transport for cases where you want to have
connections to many different peers and can't accept a large per connection
overhead, or where you want low latency for small messages.

You would use the hyper transport for cases where you have a small number of
connections, so per connection overhead does not matter that much, and where
you want maximum throughput at the expense of some latency.

This may change in the future as quic implementations get more optimized.

[quinn]: https://docs.rs/quinn/
[flume]: https://docs.rs/flume/
[iroh-quinn]: https://docs.rs/iroh-quinn/
[tokio channels]: https://docs.rs/tokio/latest/tokio/sync/index.html
[grpc]: https://grpc.io/

# Docs
Expand Down
64 changes: 0 additions & 64 deletions cliff.toml

This file was deleted.

Loading