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

[Api] add update_runtime function and return metadata from cache #337

Merged
merged 16 commits into from
Nov 29, 2022

Conversation

haerdib
Copy link
Contributor

@haerdib haerdib commented Nov 22, 2022

💥 Breaking Changes:

  • Api variables are no longer public. They should be accessed via the getter methods
  • get_metadata, get_spec_version, get_genesis_hash are now private. The user should access these values via the cached values in the Api 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, run update_runtime() before calling the cache via metadata().
  • Setter methods (such as set_signer) now take a mutable reference and do not return a Self anymore.

💚 Feature Changes:

  • Added update_runtime function to update the Api in case of a runtime upgrade
  • removes extra _get_request function: RpcClient now directly returns an Option without mapping it to an empty string and back to an Option.
  • Added some descriptive comments and split up the impl Api for a more sensible layout.

@haerdib haerdib self-assigned this Nov 22, 2022
@haerdib haerdib added F6-optimization This should optimize the performance E2-breaksapi labels Nov 22, 2022
@haerdib haerdib marked this pull request as ready for review November 22, 2022 14:38
@haerdib haerdib changed the title Api: Add update_runtime function and small clean up [Api] add update_runtime function and small clean up Nov 22, 2022
@haerdib haerdib marked this pull request as draft November 22, 2022 15:08
@haerdib haerdib marked this pull request as ready for review November 22, 2022 15:25
@haerdib haerdib changed the title [Api] add update_runtime function and small clean up [Api] add update_runtime function and return metadata from memory Nov 22, 2022
Copy link
Contributor

@echevrier echevrier left a 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();
Copy link
Contributor

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 ?

Copy link
Contributor Author

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?

Copy link
Contributor

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

Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Copy link
Collaborator

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. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed accordingly 👍

Copy link
Contributor Author

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.

Copy link
Collaborator

@clangenb clangenb left a 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.

@haerdib
Copy link
Contributor Author

haerdib commented Nov 24, 2022

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.

@haerdib
Copy link
Contributor Author

haerdib commented Nov 24, 2022

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.

Copy link
Collaborator

@clangenb clangenb left a 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. :)

Comment on lines 171 to 181
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)
}
Copy link
Collaborator

@clangenb clangenb Nov 24, 2022

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.

Copy link
Contributor Author

@haerdib haerdib Nov 24, 2022

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.

Copy link
Contributor Author

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();
Copy link
Collaborator

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.

@haerdib haerdib added the F7-enhancement Enhances an already existing functionality label Nov 28, 2022
Copy link
Contributor

@echevrier echevrier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work. Thanks

Copy link
Collaborator

@clangenb clangenb left a 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!

@haerdib haerdib changed the title [Api] add update_runtime function and return metadata from memory [Api] add update_runtime function and return metadata from cache Nov 29, 2022
@haerdib haerdib merged commit 566cea3 into master Nov 29, 2022
@haerdib haerdib deleted the bh/clean-up-api branch November 29, 2022 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E2-breaksapi F6-optimization This should optimize the performance F7-enhancement Enhances an already existing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants