Skip to content

HDDS-15682. Use the original configured host and port to identify SCM nodes#10612

Open
szetszwo wants to merge 4 commits into
apache:masterfrom
szetszwo:HDDS-15682
Open

HDDS-15682. Use the original configured host and port to identify SCM nodes#10612
szetszwo wants to merge 4 commits into
apache:masterfrom
szetszwo:HDDS-15682

Conversation

@szetszwo

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

The data structures such as SCMConnectionManager.scmMachines, StateContext.endpoint, etc. use InetSocketAddress to identify SCM nodes. Since the InetSocketAddress can changed in some environment such as Kubernetes, it is better to use the original configured host and port instead of the resolved InetSocketAddress.

What is the link to the Apache JIRA

HDDS-15682

How was this patch tested?

Updating existing tests.

@kerneltime kerneltime left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

More incoming.


public String getBlockClientAddress() {
return blockClientAddress;
return blockClientAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
return blockClientAddress.getHostAndPortString();
return blockClientAddress == null ? null : blockClientAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These HostAndPort variables in SCMNodeInfo are never null. Let's add Objects.requireNonNull in the constructor instead.


public String getScmClientAddress() {
return scmClientAddress;
return scmClientAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
return scmClientAddress.getHostAndPortString();
return scmClientAddress == null ? null : scmClientAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For comments along the same line, it is better to suggest one change and mention that the suggestion applies to other parts of the code. This makes the review less verbose, plus others do not need to respond to each similar comment.


public String getScmSecurityAddress() {
return scmSecurityAddress;
return scmSecurityAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
return scmSecurityAddress.getHostAndPortString();
return scmSecurityAddress == null ? null : scmSecurityAddress.getHostAndPortString();

}

public String getScmDatanodeAddress() {
return scmDatanodeAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
return scmDatanodeAddress.getHostAndPortString();
return scmDatanodeAddress == null ? null : scmDatanodeAddress.getHostAndPortString();

return hostAndPortString;
}

public synchronized InetSocketAddress getAddress() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why is this synchronized?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is for HDDS-15533, which will update it. Actually, let's remove it here and add it there.

@kerneltime kerneltime left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Keying SCM identity on configured host+port rather than the resolved InetSocketAddress reads as a sound fix for the IP-churn problem. A few non-blocking notes from an AI-assisted review pass below — all minor/cleanup, nothing that blocks merge.

* A class for host and port.
* It also has an address which can be updated from time to time.
*/
public class HostAndPort {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Minor (naming): this collides with Guava's com.google.common.net.HostAndPort, which is already imported in this same module at HddsUtils.java:36. It also lives in scm.net, which package-info scopes to network topology (NetworkTopology/Node/…) and which already has its own NetUtils — so the import org.apache.hadoop.net.NetUtils here shadows the same-package type. A more specific name/home (e.g. ScmEndpoint) would avoid both. Cheap while the type is new.

— Claude Code (AI-assisted review)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can replace Guava's HostAndPort with this. (Can be done in follow-up if considered out-of-scope.)

this.port = port;
this.hostAndPortString = host + ":" + port;
this.hash = host.hashCode() ^ Integer.hashCode(port);
this.address = address != null ? address : NetUtils.createSocketAddr(hostAndPortString);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The constructor resolves eagerly. For the block/client/security addresses in SCMNodeInfo the resolved value is never read — those getters return only getHostAndPortString(), and the string consumers re-resolve it (e.g. HddsUtils.getScmAddressForClients and StorageContainerManager both call NetUtils.createSocketAddr on it again) — so each ends up resolved twice and this result is discarded. Resolving lazily inside getAddress() would drop the duplicate lookup and also fits the "address can be updated from time to time" intent.

— Claude Code (AI-assisted review)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use InetSocketAddress.createUnresolved(host, port) directly instead of Hadoop's NetUtils.createSocketAddr. The latter parses the string, into host and port (so we can save this processing), and handles more complex cases that we do not need here.

@szetszwo szetszwo Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The constructor resolves eagerly ...

Use InetSocketAddress.createUnresolved(host, port) directly ...

Let's change the address resolution logic in HDDS-15533. This PR just do refactoring.

this(host, port, null);
}

public HostAndPort(InetSocketAddress address) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

equals/hashCode key on host, but this ctor derives host from address.getHostName() while the other uses the raw configured string. Those can differ (IP literal vs configured name), so two instances for the same node could be unequal and miss in the endpoint maps. It looks like this ctor is test-only today, so it's latent — but since stable host-string identity is the point of the change, might be worth dropping it or documenting that callers must use one consistent spelling.

— Claude Code (AI-assisted review)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is only used in ContainerTestUtils. Let me change the code there.

@Override
public String getAddressString() {
return getAddress().toString();
return getAddress().getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

getAddressString() is part of EndpointStateMachineMBean, so this shifts the JMX value from host/ip:port to host:port (drops the resolved IP). Intentional? Flagging only in case any monitoring parses it.

— Claude Code (AI-assisted review)

@kerneltime

Copy link
Copy Markdown
Contributor

I addressed the review comments and redid the DNS fix at szetszwo#11 please take a look.

@adoroszlai adoroszlai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @szetszwo for the patch.


public String getBlockClientAddress() {
return blockClientAddress;
return blockClientAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These HostAndPort variables in SCMNodeInfo are never null. Let's add Objects.requireNonNull in the constructor instead.


public String getScmClientAddress() {
return scmClientAddress;
return scmClientAddress.getHostAndPortString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For comments along the same line, it is better to suggest one change and mention that the suggestion applies to other parts of the code. This makes the review less verbose, plus others do not need to respond to each similar comment.

this.port = port;
this.hostAndPortString = host + ":" + port;
this.hash = host.hashCode() ^ Integer.hashCode(port);
this.address = address != null ? address : NetUtils.createSocketAddr(hostAndPortString);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use InetSocketAddress.createUnresolved(host, port) directly instead of Hadoop's NetUtils.createSocketAddr. The latter parses the string, into host and port (so we can save this processing), and handles more complex cases that we do not need here.

* A class for host and port.
* It also has an address which can be updated from time to time.
*/
public class HostAndPort {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can replace Guava's HostAndPort with this. (Can be done in follow-up if considered out-of-scope.)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants