-
Notifications
You must be signed in to change notification settings - Fork 205
server: Register raw method with connection ID #1297
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
Conversation
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
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 should work and overall I like it but some small comments to address
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
niklasad1
left a comment
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.
LGTM, nice work
I wonder if we should provide a type with connection_id() to avoid breaking it if we decide to add some other field but I think that's unlikely though.
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
jsdw
left a comment
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; just a couple of thoughts:
So, basically, register_raw_method is the same as register_async_method but with a connection ID. I'd wonder about calling it something more similar to that, eg: register_async_method_with_details (especially if the below was done).
In general I guess being able to pass Extensions between middlewares and method would remove the need for this again? But happy to just merge this and cross that bridge when we get there anyways!
I wonder if we should provide a type with connection_id() to avoid breaking it if we decide to add some other field but I think that's unlikely though.
I wondered too about wrapping the ConnectionId in a type, just to give more flexibility eg:
pub struct ConnectionDetails {
id: ConnectionId
}
impl ConnectionDetails {
pub fn id(&self) -> &ConnectionId
}…text-api-v2 Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
core/src/server/rpc_module.rs
Outdated
|
|
||
| #[derive(Debug, Clone)] | ||
| #[allow(missing_copy_implementations)] | ||
| /// The connection details exposed to the server methods. |
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 don't understand why we need the builder?
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.
The RpcService should be the last "layer" before the user-callback is called.
We construct the ConnectionDetails in this layer:
jsonrpsee/server/src/middleware/rpc/layer/rpc_service.rs
Lines 102 to 104 in 87585ad
| let connection_details = ConnectionDetails::builder().id(conn_id).build(); | |
| let fut = (callback)(id, params, connection_details, max_response_body_size); | |
| ResponseFuture::future(fut) |
I think we could just as easily provide a constructor for this:
impl ConnectionDetails {
pub fn new(id: ConnectionId) ..
}The new method needs to be public, because the ConnectionDetails is declared in the core crate. And the ConnectionDetails needs to be instantiated in the server crate as well.
We'd have to eventually change this method to new(id: ConnectionId, extensions: Extenstions) which will be a breaking change (although we should be the only ones building this object).
TLDR; since we'll do a breaking change either way, I think a new method should be fine for now! 🙏
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.
ok, I see makes sense
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.
Maybe have it be #[doc(hidden)] and comment that it's not part of the public APi and can change without notice? I don't think anything outside of jsonrpsee needs to build it, so then we could also just use new() instead of a builder (Or maybe eg _new(connection_id) to really emphasise the hiddenness of it but shrug)
core/src/server/rpc_module.rs
Outdated
| /// module.register_async_with_details("say_hello", |_params, _connection_details, _ctx| async { "lo" }).unwrap(); | ||
| /// ``` | ||
| pub fn register_raw_method<R, Fun, Fut>( | ||
| pub fn register_async_with_details<R, Fun, Fut>( |
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 not super happy about the naming register_async_with_details, it's too vague for my taste.
I would prefer register_async_method_with_conn_context or something like that
It should be obvious whether it is a method call or subscription IMO.
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 about register_async_method_eith_details? since we are provigin ConnectionDetails to it, so the word details lines up well imo :)
Co-authored-by: Niklas Adolfsson <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
…ethod_with_details` Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
…into lexnv/low-level-context-api-v2
|
We may mark this entire feature/API as What do you reckon? |
Works for me too, since I geuss we only need it internally right now and we'll break it again soon! Could also be feature flagged to hdie it at compile time and then only enable in substrate? |
Signed-off-by: Alexandru Vasile <[email protected]>
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.
rename perhaps?
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.
Have changed it to server_wtih_connection_details, thanks!
Signed-off-by: Alexandru Vasile <[email protected]>
Co-authored-by: Niklas Adolfsson <[email protected]>
…into lexnv/low-level-context-api-v2 Signed-off-by: Alexandru Vasile <[email protected]>
Signed-off-by: Alexandru Vasile <[email protected]>
… context and limit connections (#3481) This PR ensures that the chainHead RPC class can be called only from within the same connection context. The chainHead methods are now registered as raw methods. - paritytech/jsonrpsee#1297 The concept of raw methods is introduced in jsonrpsee, which is an async method that exposes the connection ID: The raw method doesn't have the concept of a blocking method. Previously blocking methods are now spawning a blocking task to handle their blocking (ie DB) access. We spawn the same number of tasks as before, however we do that explicitly. Another approach would be implementing a RPC middleware that captures and decodes the method parameters: - #3343 However, that approach is prone to errors since the methods are hardcoded by name. Performace is affected by the double deserialization that needs to happen to extract the subscription ID we'd like to limit. Once from the middleware, and once from the methods itself. This PR paves the way to implement the chainHead connection limiter: - #1505 Registering tokens (subscription ID / operation ID) on the `RpcConnections` could be extended to return an error when the maximum number of operations is reached. While at it, have added an integration-test to ensure that chainHead methods can be called from within the same connection context. Before this is merged, a new JsonRPC release should be made to expose the `raw-methods`: - [x] Use jsonrpsee from crates io (blocked by: paritytech/jsonrpsee#1297) Closes: #3207 cc @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile <[email protected]> Co-authored-by: Niklas Adolfsson <[email protected]>
… context and limit connections (#3481) This PR ensures that the chainHead RPC class can be called only from within the same connection context. The chainHead methods are now registered as raw methods. - paritytech/jsonrpsee#1297 The concept of raw methods is introduced in jsonrpsee, which is an async method that exposes the connection ID: The raw method doesn't have the concept of a blocking method. Previously blocking methods are now spawning a blocking task to handle their blocking (ie DB) access. We spawn the same number of tasks as before, however we do that explicitly. Another approach would be implementing a RPC middleware that captures and decodes the method parameters: - #3343 However, that approach is prone to errors since the methods are hardcoded by name. Performace is affected by the double deserialization that needs to happen to extract the subscription ID we'd like to limit. Once from the middleware, and once from the methods itself. This PR paves the way to implement the chainHead connection limiter: - #1505 Registering tokens (subscription ID / operation ID) on the `RpcConnections` could be extended to return an error when the maximum number of operations is reached. While at it, have added an integration-test to ensure that chainHead methods can be called from within the same connection context. Before this is merged, a new JsonRPC release should be made to expose the `raw-methods`: - [x] Use jsonrpsee from crates io (blocked by: paritytech/jsonrpsee#1297) Closes: #3207 cc @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile <[email protected]> Co-authored-by: Niklas Adolfsson <[email protected]>
… context and limit connections (paritytech#3481) This PR ensures that the chainHead RPC class can be called only from within the same connection context. The chainHead methods are now registered as raw methods. - paritytech/jsonrpsee#1297 The concept of raw methods is introduced in jsonrpsee, which is an async method that exposes the connection ID: The raw method doesn't have the concept of a blocking method. Previously blocking methods are now spawning a blocking task to handle their blocking (ie DB) access. We spawn the same number of tasks as before, however we do that explicitly. Another approach would be implementing a RPC middleware that captures and decodes the method parameters: - paritytech#3343 However, that approach is prone to errors since the methods are hardcoded by name. Performace is affected by the double deserialization that needs to happen to extract the subscription ID we'd like to limit. Once from the middleware, and once from the methods itself. This PR paves the way to implement the chainHead connection limiter: - paritytech#1505 Registering tokens (subscription ID / operation ID) on the `RpcConnections` could be extended to return an error when the maximum number of operations is reached. While at it, have added an integration-test to ensure that chainHead methods can be called from within the same connection context. Before this is merged, a new JsonRPC release should be made to expose the `raw-methods`: - [x] Use jsonrpsee from crates io (blocked by: paritytech/jsonrpsee#1297) Closes: paritytech#3207 cc @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile <[email protected]> Co-authored-by: Niklas Adolfsson <[email protected]>
This PR exposes the connection ID to raw methods.
To achieve this, a new
register_raw_methodis exposed on the RpcModule.The
with-contextattribute is implemented in the proc-macros to use this method.When the
with-contextattribute is used, all methods of a server are rendered with an extra connection Id parameter.This is similar to the
PendingSubscriptionSinkthat is injected into subscription methods.Examples
The example
server_with_contextimplements a server with the context attribute enabled.A function of the server returns the connection ID from its parameters.
Users on different connections will receive a different connection ID.
Testing
with-context, sync methods and blocking methodsA simplified version of #1295, that avoids a user-breaking change.