-
Notifications
You must be signed in to change notification settings - Fork 127
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
[Api] add update_runtime
function and return metadata from cache
#337
Conversation
update_runtime
function and small clean upupdate_runtime
function and small clean up
update_runtime
function and small clean upupdate_runtime
function and return metadata from memory
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.
Only one question.
|
||
match version { | ||
Some(v) => serde_json::from_str(&v).map_err(|e| e.into()), | ||
None => Err(ApiClientError::RuntimeVersion), | ||
} | ||
} | ||
|
||
fn _get_metadata(client: &Client) -> ApiResult<RuntimeMetadataPrefixed> { | ||
pub fn get_metadata_from_node(client: &Client) -> ApiResult<RuntimeMetadataPrefixed> { | ||
let jsonreq = json_req::state_get_metadata(); |
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 names get_metadata
, get_metadata_from_node
(and similar ones) are a bit confusing, as if the metadata returned by get_metadata
is not the node's metadata. The difference is not the source of the metadata, but its currentness.
Wouldn't it be better to have get_cached_metadata
for get_metadata
and let get_metadata
for get_metadata_from_node
?
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 see your point, but I think the get_metadata
should stay as is, because that should be the usual way to retrieve the metadata. Getting the metadata from the node should be the non-normal way, therefore warranting the longer name, I believe.
How about query_metadata_from_node
?
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.
Perfect. That's clear. Thanks
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 are mixing concepts here, get_*
sometimes performs a network request now, and sometimes it does not, this inconsistency is confusing.
I suggest get_*
always talks to the node, then we don't need to distinguish between query_metadata_from_node
to emphasize that it actually does the same as most of the get_*
calls.
We don't have to re-invent the wheel here, we can just do:
api.metadata()
is a simple getter to the field
api.get_metdata()
is the network request, however, do we even want to keep it?
Same for the runtime version.
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.
api.get_metdata() is the network request, however, do we even want to keep it?
Not sure. We need a private node query method, because the api needs it to be able to update the cached metdata, but it does not need to be public.. because one could just run update_...
and then query the cached metadata.
I don't have a strong opinion here, but well.. why not make it private and force the user to update cached metadata if up-to-date metadata is needed.
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 have a strong opinion here, but well.. why not make it private and force the user to update cached metadata if up-to-date metadata is needed.
This seems good to me! However, the private one should still be get_metadata
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.
Renamed accordingly 👍
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.
Also restructured a little, because it was veery chaotic. Updated the PR description accordingly to what has been changed.
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.
May I ask what was the rationale behind adding metadata as a field?
Spontaneously, I think I would prefer that the Api is stateless to prevent errors of inconsistency.
If the metadata is not cached, that means for every extrinsic sent (online), the metadata, runtime version and such need to be queried first. Not sure if that's smart in regard to optimization. |
Just checked: The metadata field has been there since 2019, so I guess I can't answer the original rationale, but I suppose the speed is a concern. |
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 also have a remark about the naming, but otherwise it looks good. I totally agree about the metadata caching now. :)
src/api/api_client.rs
Outdated
pub fn update_runtime(mut self) -> ApiResult<Self> { | ||
let metadata = Self::get_metadata_from_node(&self.client).map(Metadata::try_from)??; | ||
debug!("Metadata: {:?}", metadata); | ||
|
||
let runtime_version = Self::get_runtime_version_from_node(&self.client)?; | ||
info!("Runtime Version: {:?}", runtime_version); | ||
|
||
self.metadata = metadata; | ||
self.runtime_version = runtime_version; | ||
Ok(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.
I think this should be pub fn update_runtime(&mut self) -> ApiResult<Metadata>
. The mut self
is rather used for the builder pattern and not the object itself (btw. I think the setSigner
method should also be changed).
I don't know if we want to return anything at all, it could also just be ()
, I don't like the naming 100%, but I can't come up with a better one 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.
Agreed. Tried to be consistent, with what's there already, but passing a mut reference is more common.
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.
Done :)
|
||
match version { | ||
Some(v) => serde_json::from_str(&v).map_err(|e| e.into()), | ||
None => Err(ApiClientError::RuntimeVersion), | ||
} | ||
} | ||
|
||
fn _get_metadata(client: &Client) -> ApiResult<RuntimeMetadataPrefixed> { | ||
pub fn get_metadata_from_node(client: &Client) -> ApiResult<RuntimeMetadataPrefixed> { | ||
let jsonreq = json_req::state_get_metadata(); |
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 are mixing concepts here, get_*
sometimes performs a network request now, and sometimes it does not, this inconsistency is confusing.
I suggest get_*
always talks to the node, then we don't need to distinguish between query_metadata_from_node
to emphasize that it actually does the same as most of the get_*
calls.
We don't have to re-invent the wheel here, we can just do:
api.metadata()
is a simple getter to the field
api.get_metdata()
is the network request, however, do we even want to keep it?
Same for the runtime version.
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.
Nice work. Thanks
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 have a question, but it looks very clean to me otherwise!
f6a2852
to
71f88c1
Compare
update_runtime
function and return metadata from memoryupdate_runtime
function and return metadata from cache
💥 Breaking Changes:
Api
variables are no longer public. They should be accessed via the getter methodsget_metadata
,get_spec_version
,get_genesis_hash
are now private. The user should access these values via the cached values in theApi
struct.❗ Careful: In case one relied on
get_metadata
returning the most recent metadata from the node, that's not the case any more. If that's necessary, runupdate_runtime()
before calling the cache viametadata()
.set_signer
) now take a mutable reference and do not return aSelf
anymore.💚 Feature Changes:
update_runtime
function to update the Api in case of a runtime upgrade_get_request
function: RpcClient now directly returns anOption
without mapping it to an empty string and back to an Option.impl Api
for a more sensible layout.