Skip to content

Conversation

@DaveCTurner
Copy link
Contributor

Today RoutingNode#initializing, RoutingNode#started and
RoutingNode#relocating all work by copying the result into a freshly
allocated array. These collections are immutable and all the
(production) callers immediately iterate over the result so the copy is
unnecessary. Moreover the started collection in particular might be
huge.

This commit adjusts these methods to return an iterator over the
underlying collection instead, asserting that the resulting iterators
are never mutated.

Closes ES-13364

Today `RoutingNode#initializing`, `RoutingNode#started` and
`RoutingNode#relocating` all work by copying the result into a freshly
allocated array. These collections are immutable and all the
(production) callers immediately iterate over the result so the copy is
unnecessary. Moreover the `started` collection in particular might be
huge.

This commit adjusts these methods to return an iterator over the
underlying collection instead, asserting that the resulting iterators
are never mutated.

Closes ES-13364
@DaveCTurner DaveCTurner requested a review from ywangd November 6, 2025 15:59
@DaveCTurner DaveCTurner requested a review from a team as a code owner November 6, 2025 15:59
@DaveCTurner DaveCTurner added :Distributed Coordination/Allocation All issues relating to the decision making around placing a shard (both master logic & on the nodes) v9.3.0 labels Nov 6, 2025
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-distributed-coordination (Team:Distributed Coordination)

@elasticsearchmachine elasticsearchmachine added the Team:Distributed Coordination Meta label for Distributed Coordination team label Nov 6, 2025
@elasticsearchmachine
Copy link
Collaborator

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

Copy link
Contributor

@henningandersen henningandersen left a comment

Choose a reason for hiding this comment

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

Looks good though I'd find Iterable slightly better?


public ShardRouting[] initializing() {
return initializingShards.toArray(EMPTY_SHARD_ROUTING_ARRAY);
public Iterator<ShardRouting> initializing() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd find it slightly more intuitive to return an Iterable here, to preserve the native for loop construct rather than the old while iterator style. Is there a reason you went for the iterator?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Iterable implies you can iterate it more than once but we don't actually do so anywhere. Also a bit more of a pain to assert nobody tries to remove anything from the resulting iterator. Not a watertight argument but we do have more utilities for working with an Iterator too.

Copy link
Contributor

Choose a reason for hiding this comment

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

a bit more of a pain to assert nobody tries to remove anything from the resulting iterator

Not sure I follow, would it not simply (or just 🧌) be implemented by:

() -> Iterators.assertReadOnly(initializingShards.iterator())

i.e., the implementation is straightforward (and we avoid the 3 lines of code per for loop).

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 skipping this lambda construction when assertions disabled but yeah only a bit more of a pain.

Copy link
Member

@ywangd ywangd left a comment

Choose a reason for hiding this comment

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

LGTM

assert initializingShardsIterator.hasNext();
final var initializingShard = initializingShardsIterator.next();
assert initializingShardsIterator.hasNext() == false
: "expect exactly one relocating shard, but got: " + Iterators.toList(initializingShardsIterator);
Copy link
Member

Choose a reason for hiding this comment

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

Nit:

Suggested change
: "expect exactly one relocating shard, but got: " + Iterators.toList(initializingShardsIterator);
: "expect exactly one relocating shard, but got: [" + initializingShard + "] and " + Iterators.toList(initializingShardsIterator);

@DaveCTurner DaveCTurner enabled auto-merge (squash) November 7, 2025 07:51
Copy link
Contributor

@henningandersen henningandersen left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Distributed Coordination/Allocation All issues relating to the decision making around placing a shard (both master logic & on the nodes) >enhancement Team:Distributed Coordination Meta label for Distributed Coordination team v9.3.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants