-
Notifications
You must be signed in to change notification settings - Fork 173
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: async API when Response
has been processed.
#1281
Conversation
RpcModule::register_raw_method
RpcModule::register_raw_method
+ ResponsePayload async API
Overall looks good to me, nice one 👍 ! And in combination with the polkadot-sdk commit this should resolve any races from happening. I find the |
Yeah, agree. I don't like it either I thought it was nice wrapper but it makes things more confusing. Removed now thanks. |
core/src/server/method_response.rs
Outdated
|
||
/// Optional callback that may be utilized to notify that the method response was a | ||
/// an JSON-RPC error object and processed. | ||
pub fn notify_on_error(mut self, tx: MethodResponseNotifyTx) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How this is set up at the moment means that if somebody does:
response
.notify_on_success(...)
.notify_on_error(...)
.notify_on_response(...)
They get no compile error, and they might expect one of those to fire in each case, but in fact only the last registered one has any chance of ever firing.
I guess I'd prevent this by:
- Either have more than one callback that can be registered, or
- Just have
notify_on_completion
or something and indicate by the channel response whether success or error happened.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though I'd also probably want it so that response.notify_on_completion(a).notify_on_completion(b)
also worked and fired both a and b; one could store a vec of things-to-be-notified perhaps? Or change the method name to eg set_on_complete_notifier(..)
so that it was a bit more obvious that it set a single thing rather than allowed multiple notifications to be given.
@@ -109,10 +105,20 @@ impl RpcDescription { | |||
let ret_ty = args.last_mut().unwrap(); | |||
let err_ty = self.jrps_client_item(quote! { core::client::Error }); | |||
|
|||
quote! { core::result::Result<#ret_ty, #err_ty> } | |||
} else if type_name.ident == "ResponsePayload" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sad that we have to match on the string type names :D
I guess it wasn't possible to use a trait to convert these into results automatically or something; I'm sure it was something like that but can't remember the issue now! But ah well!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nah, it's that the client codegen is super opinionated and the error type must be jsonrpsee::core::client::Error
otherwise it won't compile. Yeah, it's ugly but just proc macro code thank god.
IntoResponse stuff doesn't work there because we have deal with I/O errors and bunch of things in the client code
Looks good to me; the only actual thing I think should be addressed is making |
@@ -31,7 +30,7 @@ impl IntoResponse for CustomError { | |||
let data = data.map(|val| serde_json::value::to_raw_value(&val).unwrap()); | |||
|
|||
let error_object = jsonrpsee::types::ErrorObjectOwned::owned(code, "custom_error", data); | |||
ResponsePayload::Error(error_object) | |||
ResponsePayload::error(error_object) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the breaking change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aaahhh I see! I was thinking of something else :)
(I guess if you wanted to do a patch release and didn't mind it being a bit ugly you could have an Error
method)
@@ -4,8 +4,7 @@ use std::net::SocketAddr; | |||
|
|||
use jsonrpsee::core::{async_trait, ClientError, Serialize}; | |||
use jsonrpsee::proc_macros::rpc; | |||
use jsonrpsee::server::{IntoResponse, ServerBuilder}; | |||
use jsonrpsee::types::ResponsePayload; | |||
use jsonrpsee::server::{IntoResponse, ResponsePayload, ServerBuilder}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a breaking change as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aah I see; it moved! So will you do a proper release then instead of a patch one do you think? Or alias this type in jsonrpsee::types
in the release to avoid this break?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have to make a proper release because the MethodResponse is also a breaking change and I can't do proper alias in types because then the feature flag core/server
needs to be enabled for ResponsePayload to be available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me offhand!
It feels like we'll need to do a major release given the breaks unless you mangle a couple of things in a patch release to keep the old APIs/imports :)
@@ -0,0 +1,84 @@ | |||
// Copyright 2019-2021 Parity Technologies (UK) Ltd. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Maybe copyright years need to change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's take of it in another PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
Response
has been processed.
core/src/server/method_response.rs
Outdated
/// | ||
/// This is useful when one only want to return the error and | ||
/// `T` can't resolved by rustc to avoid type annonations. | ||
pub fn unit_error(e: impl Into<ErrorObjectOwned>) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you first mentioned it I assumed it meant error is ()
which is what confused me :D
That said, I'm struggling to come up with a better name! I'm ok with just doing ResponsePayload::<()>::error(err)
too I guess; if thename for any longer you'd not be saving any chars any more anyways!
Resolves #1279