Skip to content

Run cluster info requests on local node #120982

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

Closed
wants to merge 5 commits into from

Conversation

nielsbauman
Copy link
Contributor

The actions GetIndex, GetMapping, and ExplainLifecycle (ILM) solely need the cluster state, they can run on any node.

The actions `GetIndex`, `GetMapping`, and `ExplainLifecycle` (ILM)
solely need the cluster state, they can run on any node.
@nielsbauman nielsbauman added >enhancement :Data Management/Indices APIs APIs to create and manage indices and templates Team:Data Management Meta label for data/management team v9.0.0 labels Jan 28, 2025
Copy link
Contributor

Documentation preview:

@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-data-management (Team:Data Management)

@elasticsearchmachine
Copy link
Collaborator

Hi @nielsbauman, I've created a changelog YAML for you.

Comment on lines -68 to -71
},
"local":{
"type":"boolean",
"description":"Return local information, do not retrieve the state from master node (default: false)"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This param for the GetFieldMapping API was deprecated in #55014 and I think #57265 aimed to propagate that deprecation to the REST API spec, but it changed get_mapping.json instead of get_field_mapping.json. #55100 removed the local param for the field mapping API but the regular mapping API still supports the local param. That's why I'm deleting the param here and deprecating it in get_mapping.json below.

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you pull this out to a separate PR?

@@ -516,16 +514,6 @@ public void testDeleteIndex() {
assertSameIndices(deleteIndexRequest, TransportDeleteIndexAction.TYPE.name());
}

public void testGetMappings() {
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 deleted this test because it didn't seem to make much sense to keep it when we run the action on the local node -- and it was failing.

Comment on lines +97 to +100
/**
* Even though this action is executed on the local node, we still need to be able to read an incoming request as it's used across
* clusters.
*/
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one is worth discussing. It looks like the GetIndexAction is used across clusters:

public static final RemoteClusterActionType<GetIndexResponse> REMOTE_TYPE = new RemoteClusterActionType<>(NAME, GetIndexResponse::new);

which means we'll need to support transport serialization for both GetIndexRequest and GetIndexResponse. That in turn meant I had to remove final LocalClusterStateRequest#writeTo (see further down this PR). I don't really see a way around this but any suggestions are welcome.

We could also add final back into LocalClusterStateReuqest#writeTo and add a method like writeToRemoteCluster to something along those lines, to make it more explicit that that method is required for cross-cluster requests.

@@ -177,7 +172,7 @@ static IndexLifecycleExplainResponse getIndexLifecycleExplainResponse(
lifecycleState.phase(),
lifecycleState.action(),
// treat a missing policy as if the index is in the error step
indexLifecycleService.policyExists(policyName) == false ? ErrorStep.NAME : lifecycleState.step(),
policyExists == false ? ErrorStep.NAME : lifecycleState.step(),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The IndexLifecycleService only runs on the master node, which meant that policyExists was always false. I changed it to use the Metadata to check for policy existence.

Copy link
Contributor

@DaveCTurner DaveCTurner left a comment

Choose a reason for hiding this comment

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

TBH I'm not really sure what the ClusterInfoAction abstraction is for. Aren't there lots of other things that could be such an action? They don't really return info about a cluster either.

I think I'd rather we tried to separate out the remote-cluster side of this somehow. Maybe set up something that proxies to the local-cluster action and handles the wire protocol.

@Override
public final void writeTo(StreamOutput out) throws IOException {
public void writeTo(StreamOutput out) throws IOException {
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah I don't really like removing this final. I think I'd rather we just made TransportGetIndexAction extends HandledTransportAction rather than trying to generalize TransportClusterInfoAction for this one special case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm that means we'd have to re-implement/copy the code to wait for cluster blocks. Also, the TransportClusterStateAction faces the same issue -- and that one also needs to wait for the master in the cluster state.
We can try extracting that waiting logic so TransportLocalClusterStateAction, TransportGetIndexAction, and TransportClusterStateAction can share it, but that might get a bit ugly.

@nielsbauman
Copy link
Contributor Author

@DaveCTurner

TBH I'm not really sure what the ClusterInfoAction abstraction is for.

I guess it's only to avoid storing indices and indicesOptions in extending classes. But I agree that that value seems rather minimal as we have plenty of classes that define those fields themselves. I'd also be OK with getting rid of the ClusterInfoAction abstraction first (in separate PRs) and converting these requests individually, but that would be more of a standalone cleanup as I don't think it is strongly related to what we're trying to do here.

@DaveCTurner
Copy link
Contributor

I don't think it is strongly related to what we're trying to do here.

It'd mean that we no longer had GetIndexRequest extends ClusterInfoRequest and therefore had to make the abstract ClusterInfoRequest serializable even though all its other implementations are local-only.

I think the proxy action idea should work out ok: separate out the remote-cluster get-index action and register this remote-only action with the transport service, then have it simply delegate into the local-node-only get-index action.

@nielsbauman
Copy link
Contributor Author

@DaveCTurner alright, I'll work on removing the ClusterInfo abstraction.

About your proxy action idea, the proxy action would use the same request and response classes, right? Where would you define the wire (de)serialization?

@DaveCTurner
Copy link
Contributor

I would have a different request class for the proxy action, extending TransportRequest rather than ClusterInfoRequest. That way you can define the wire protocol there, plus some simple way to convert it into the ClusterInfoRequest for local execution.

I believe you will be able to register the proxy action with the TransportService and the genuine action with the ActionModule under the same action name.

@nielsbauman
Copy link
Contributor Author

Wouldn't that require duplicating all the fields between the GetIndexRequest (plus the ones in ClusterInfoRequest) and the remote request class? Those fields would then also have to be kept in sync to avoid incompatibilities between the local and remote requests.

I thought about the alternative of making TransportGetIndexAction extend HandledTransportAction instead as that would allow us to keep the serialization without any issues. However, that would mean that we'd have to copy over the execution code of TransportLocalClusterStateAction that waits for the cluster block etc.

@DaveCTurner
Copy link
Contributor

Wouldn't that require duplicating all the fields

I'd expect us to pull out a record for all the common fields rather than just blindly duplicating them one-by-one.

making TransportGetIndexAction extend HandledTransportAction instead

Yeah that seems like it'd lead to worse duplication problems.

@nielsbauman
Copy link
Contributor Author

Closing this in favor of #125652 as that's the last remaining ClusterInfo action that is converted to run on the local node.

The serialization issue we talked about in this PR is no longer relevant as the cross-cluster usage of the GET index API is obsolete and will be removed soon. See #125652 (comment)

@nielsbauman nielsbauman deleted the local-cluster-info branch March 26, 2025 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Data Management/Indices APIs APIs to create and manage indices and templates >enhancement Team:Data Management Meta label for data/management team v9.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants