Skip to content

NodeInfo response should use a collection rather than fields #54460

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

williamrandolph
Copy link
Contributor

When the nodes info endpoint is pluggable, the NodeInfo objects will need to be able to hold more than just a known group of heterogeneous objects representing different kinds of information. To this end, this PR introduces a ReportingService.Info interface, which each of the component info objects now inherits. The NodeInfo class can then replace its individual fields with a collection of ReportingService.Info objects. For this collection, I've chosen a map keyed on object type, which gives us the ability to handle casting dynamically in the getInfo() method. I'm open to alternate approaches.

I'm leaving the serialization of the NodeInfo object alone until I'm sure about how it should look in the long term. We don't want to get stuck supporting an intermediate serialization in future releases. (See #54305 for context.)

Relates #52975

This is a first cut at giving NodeInfo the ability to carry a flexible
list of heterogeneous info responses. The trick is to be able to
serialize and deserialize an arbitrary list of blocks of information. It
is convenient to be able to deserialize into usable Java objects so that
we can aggregate nodes stats for the cluster stats endpoint.

In order to provide a little bit of clarity about which objects can and
can't be used as info blocks, I've introduced a new interface called
"ReportingService."
I tried a different serialization for NodeInfo that would allow writing
flexible, arbitrary lists of node info blocks, but it seems too early in
the process to commit to anything definite, so I've backed out the
change.

I have removed the hard-coded getters (e.g., getOs()) in favor of a
flexible method that can return heterogeneous kinds of info blocks
(e.g., getInfo(OsInfo.class)). Taking a class as an argument removes the
need to cast in the client code.
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (:Core/Infra/Plugins)

}

@Nullable
public ByteSizeValue getTotalIndexingBuffer() {
return totalIndexingBuffer;
}

private void addInfoIfNonNull(Class<? extends ReportingService.Info> clazz, ReportingService.Info info) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybename it maybeAddInfo(...)? I'm unsure if that's an improvement.

Copy link
Contributor

@pugnascotia pugnascotia left a comment

Choose a reason for hiding this comment

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

I'm not mad keen on using classes as a keys, but I'm struggling to think of an alternative, so LGTM.

@williamrandolph
Copy link
Contributor Author

The alternative I can think of is just returning a ReportingService.Info object and letting the client code handle the casting if it needs to.

The strategy for heterogeneous containers that I've chosen here is discussed in Effective Java, 2nd Edition, item 29: "Consider typesafe heterogeneous containers".

Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

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

This is a clever approach. I think it will make using the new response a lot easier extracting a typed info. The one caveat is it means we need to ensure each info type class is unique when registering services with infos, but that is for later. LGTM!

@williamrandolph
Copy link
Contributor Author

@elasticmachine please run elasticsearch-ci/2

@williamrandolph williamrandolph merged commit 633790f into elastic:master Apr 13, 2020
@williamrandolph williamrandolph deleted the nodes-info-response-fields-to-collection branch April 13, 2020 19:48
williamrandolph added a commit to williamrandolph/elasticsearch that referenced this pull request Apr 13, 2020
…#54460)

This is a first cut at giving NodeInfo the ability to carry a flexible
list of heterogeneous info responses. The trick is to be able to
serialize and deserialize an arbitrary list of blocks of information. It
is convenient to be able to deserialize into usable Java objects so that
we can aggregate nodes stats for the cluster stats endpoint.

In order to provide a little bit of clarity about which objects can and
can't be used as info blocks, I've introduced a new interface called
"ReportingService."

I have removed the hard-coded getters (e.g., getOs()) in favor of a
flexible method that can return heterogeneous kinds of info blocks
(e.g., getInfo(OsInfo.class)). Taking a class as an argument removes the
need to cast in the client code.
williamrandolph added a commit that referenced this pull request Apr 13, 2020
…#55132)

This is a first cut at giving NodeInfo the ability to carry a flexible
list of heterogeneous info responses. The trick is to be able to
serialize and deserialize an arbitrary list of blocks of information. It
is convenient to be able to deserialize into usable Java objects so that
we can aggregate nodes stats for the cluster stats endpoint.

In order to provide a little bit of clarity about which objects can and
can't be used as info blocks, I've introduced a new interface called
"ReportingService."

I have removed the hard-coded getters (e.g., getOs()) in favor of a
flexible method that can return heterogeneous kinds of info blocks
(e.g., getInfo(OsInfo.class)). Taking a class as an argument removes the
need to cast in the client code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants