Releases: paritytech/jsonrpsee
v0.20.2
[v0.20.2] - 2023-10-13
This release removes the bounded buffer check which was intended to provide
backpressure all the way down to the TCP layer but it didn't work well.
For subscriptions the backpressure will be handled by implementation itself
and just rely on that.
[Changed]
- server: remove bounded channel check (#1209)
v0.20.1
[v0.20.1] - 2023-09-15
This release adds support for synchronous subscriptions
and fixes a leak in WebSocket server
where FuturesUnordered was not getting polled until shutdown, so it was accumulating tasks forever.
[Changed]
- client: downgrade log for unknown subscription to DEBUG (#1185)
- refactor(http client): use HTTP connector on http URLs (#1187)
- refactor(server): less alloc per method call (#1188)
[Fixed]
- fix: remove needless clone in ws background task (#1203)
- async client: save latest Waker (#1198)
- chore(deps): bump actions/checkout from 3.6.0 to 4.0.0 (#1197)
- fix(server): fix leak in FuturesUnordered (#1204)
[Added]
- feat(server): add sync subscription API
register_subscription_raw
(#1182)
v0.16.3
[v0.16.3] - 2023-08-23
This release fixes https://rustsec.org/advisories/RUSTSEC-2023-0052.
v0.20.0
[v0.20.0] - 2023-08-11
Another breaking release where the major changes are:
host filtering
has been moved to tower middleware instead of the server API.- the clients now supports default port number such
wss://my.server.com
- the background task for the async client has been refactored to multiplex send and read operations.
Regarding host filtering prior to this release one had to do:
let acl = AllowHosts::Only(vec!["http://localhost:*".into(), "http://127.0.0.1:*".into()]);
let server = ServerBuilder::default().set_host_filtering(acl).build("127.0.0.1:0").await.unwrap();
After this release then one have to do:
let middleware = tower::ServiceBuilder::new().layer(HostFilterLayer::new(["example.com"]).unwrap());
let server = Server::builder().set_middleware(middleware).build("127.0.0.1:0".parse::<SocketAddr>()?).await?;
Thanks to the external contributors @polachok, @bobs4462 and @aj3n that contributed to this release.
[Added]
- feat(server): add
SubscriptionMessage::new
(#1176) - feat(server): add
SubscriptionSink::connection_id
(#1175) - feat(server): add
Params::get
(#1173) - feat(server): add
PendingSubscriptionSink::connection_id
(#1163)
[Fixed]
- fix(server): host filtering URI read authority (#1178)
[Changed]
- refactor: make ErrorObject::borrowed accept
&str
(#1160) - refactor(client): support default port number (#1172)
- refactor(server): server host filtering (#1174)
- refactor(client): refactor background task (#1145)
- refactor: use
RootCertStore::add_trust_anchors
(#1165) - chore(deps): update criterion v0.5 and pprof 0.12 (#1161)
- chore(deps): update webpki-roots requirement from 0.24 to 0.25 (#1158)
- refactor(server): move host filtering to tower middleware (#1179)
V0.19.0
v0.18.2
v0.18.1
This release fixes a couple bugs and improves the ergonomics for the HTTP client
when no tower middleware is enabled.
Changed
- http client: add default generic param for the backend (#1099)
Fixed
v0.18.0
[v0.18.0] - 2023-04-21
This is a breaking release that removes the CallError
which was used to represent a JSON-RPC error object that
could happen during JSON-RPC method call and one could assign application specific error code, message and data in a
specific implementation.
Previously jsonrpsee provided CallError
that could be converted to/from jsonrpsee::core::Error
and in some scenarios the error code was automatically assigned by jsonrpsee. After jsonrpsee
added support for custom error types the CallError
doesn't provide any benefit because one has to implement Into<ErrorObjectOwned>
on the error type anyway.
Thus, jsonrpsee::core::Error
can't be used in the proc macro API anymore and the type alias
RpcResult
has been modified to Result<(), ErrorObjectOwned>
instead.
Before it was possible to do:
#[derive(thiserror::Error)]
enum Error {
A,
B,
}
#[rpc(server, client)]
pub trait Rpc
{
#[method(name = "getKeys")]
async fn keys(&self) -> Result<String, jsonrpsee::core::Error> {
Err(jsonrpsee::core::Error::to_call_error(Error::A))
// or jsonrpsee::core::Error::Call(CallError::Custom(ErrorObject::owned(1, "a", None::<()>)))
}
}
After this change one has to do:
pub enum Error {
A,
B,
}
impl From<Error> for ErrorObjectOwned {
fn from(e: Error) -> Self {
match e {
Error::A => ErrorObject::owned(1, "a", None::<()>),
Error::B => ErrorObject::owned(2, "b", None::<()>),
}
}
}
#[rpc(server, client)]
pub trait Rpc {
// Use a custom error type that implements `Into<ErrorObject>`
#[method(name = "custom_err_ty")]
async fn custom_err_type(&self) -> Result<String, Error> {
Err(Error::A)
}
// Use `ErrorObject` as error type directly.
#[method(name = "err_obj")]
async fn error_obj(&self) -> RpcResult<String> {
Err(ErrorObjectOwned::owned(1, "c", None::<()>))
}
}
[Changed]
- remove
CallError
(#1087)
[Fixed]
- fix(proc macros): support parsing params !Result (#1094)
v0.17.1
v0.17.0
This is a significant release and the major breaking changes to be aware of are:
Server backpressure
This release changes the server to be "backpressured" and it mostly concerns subscriptions.
New APIs has been introduced because of that and the API pipe_from_stream
has been removed.
Before it was possible to do:
module
.register_subscription("sub", "s", "unsub", |_, sink, _| async move {
let stream = stream_of_integers();
tokio::spawn(async move {
sink.pipe_from_stream(stream)
});
})
.unwrap();
After this release one must do something like:
// This is just a example helper.
//
// Other examples:
// - <https://github.com/paritytech/jsonrpsee/blob/master/examples/examples/ws_pubsub_broadcast.rs>
// - <https://github.com/paritytech/jsonrpsee/blob/master/examples/examples/ws_pubsub_with_params.rs>
async fn pipe_from_stream<T: Serialize>(
pending: PendingSubscriptionSink,
mut stream: impl Stream<Item = T> + Unpin,
) -> Result<(), anyhow::Error> {
let mut sink = pending.accept().await?;
loop {
tokio::select! {
_ = sink.closed() => break Ok(()),
maybe_item = stream.next() => {
let Some(item) = match maybe_item else {
break Ok(()),
};
let msg = SubscriptionMessage::from_json(&item)?;
if let Err(e) = sink.send_timeout(msg, Duration::from_secs(60)).await {
match e {
// The subscription or connection was closed.
SendTimeoutError::Closed(_) => break Ok(()),
/// The subscription send timeout expired
/// the message is returned and you could save that message
/// and retry again later.
SendTimeoutError::Timeout(_) => break Err(anyhow::anyhow!("Subscription timeout expired")),
}
}
}
}
}
}
module
.register_subscription("sub", "s", "unsub", |_, pending, _| async move {
let stream = stream();
pipe_from_stream(sink, stream).await
})
.unwrap();
Method call return type is more flexible
This release also introduces a trait called IntoResponse
which is makes it possible to return custom types and/or error
types instead of enforcing everything to return Result<T, jsonrpsee::core::Error>
This affects the APIs RpcModule::register_method
, RpcModule::register_async_method
and RpcModule::register_blocking_method
and when these are used in the proc macro API are affected by this change.
Be aware that the client APIs don't support this yet
The IntoResponse
trait is already implemented for Result<T, jsonrpsee::core::Error>
and for the primitive types
Before it was possible to do:
// This would return Result<&str, jsonrpsee::core::Error>
module.register_method("say_hello", |_, _| Ok("lo"))?;
After this release it's possible to do:
// Note, this method call is infallible and you might not want to return Result.
module.register_method("say_hello", |_, _| "lo")?;
Subscription API is changed.
jsonrpsee now spawns the subscriptions via tokio::spawn
and it's sufficient to provide an async block in register_subscription
Further, the subscription API had an explicit close API for closing subscriptions which was hard to understand and
to get right. This has been removed and everything is handled by the return value/type of the async block instead.
Example:
module
.register_subscription::<RpcResult<(), _, _>::("sub", "s", "unsub", |_, pending, _| async move {
// This just answers the RPC call and if this fails => no close notification is sent out.
pending.accept().await?;
// This is sent out as a `close notification/message`.
Err(anyhow::anyhow!("The subscription failed"))?;
})
.unwrap();
The return value in the example above needs to implement IntoSubscriptionCloseResponse
and
any value that is returned after that the subscription has been accepted will be treated as a IntoSubscriptionCloseResponse
.
Because Result<(), E>
is used here the close notification will be sent out as error notification but it's possible to
disable the subscription close response by using ()
instead of Result<(), E>
or implement IntoSubscriptionCloseResponse
for other behaviour.
[Added]
- feat(server): configurable limit for batch requests. (#1073)
- feat(http client): add tower middleware (#981)
[Fixed]
- add tests for ErrorObject (#1078)
- fix: tokio v1.27 (#1062)
- fix: remove needless
Semaphore::(u32::MAX)
(#1051) - fix server: don't send error on JSON-RPC notifications (#1021)
- fix: add
max_log_length
APIs and use missing configs (#956) - fix(rpc module): subscription close bug (#1011)
- fix: customized server error codes (#1004)
[Changed]
- docs: introduce workspace attributes and add keywords (#1077)
- refactor(server): downgrade connection log (#1076)
- chore(deps): update webpki-roots and tls (#1068)
- rpc module: refactor subscriptions to return
impl IntoSubscriptionResponse
(#1034) - add
IntoResponse
trait for method calls (#1057) - Make
jsonrpc
protocol version field inResponse
asOption
(#1046) - server: remove dependency http (#1037)
- chore(deps): update tower-http requirement from 0.3.4 to 0.4.0 (#1033)
- chore(deps): update socket2 requirement from 0.4.7 to 0.5.1 (#1032)
- Update bound type name (#1029)
- rpc module: remove
SubscriptionAnswer
(#1025) - make verify_and_insert pub (#1028)
- update MethodKind (#1026)
- remove batch response (#1020)
- remove debug log (#1024)
- client: rename
max_notifs_per_subscription
tomax_buffer_capacity_per_subscription
(#1012) - client: feature gate tls cert store (#994)
- server: bounded channels and backpressure (#962)
- client: use tokio channels (#999)
- chore: update gloo-net ^0.2.6 (#978)
- Custom errors (#977)
- client: distinct APIs to configure max request and response sizes (#967)
- server: replace
FutureDriver
withtokio::spawn
(#1080) - server: uniform whitespace handling in rpc calls (#1082)