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

CURATOR-535: Fix client port conflict due to untrustworthy random port allocation #421

Conversation

kezhuw
Copy link
Member

@kezhuw kezhuw commented Jun 14, 2022

This commit tries to solve port conflict for TestingServer if port is unspecified(aka. port <= 0):

  • Set InstanceSpec.port to 0 if port is unspecified.
  • Save OS chosen bind port after started to maintain same port across restart.

Ideally, it should be possible to bootstrap TestingCluster(with unspecified ports) too with help from reconfig. But there are difficulties since election port, quorum port were not designed to be bound to 0 in ZooKeeper. TestingServer should be enough for most cases.

Users should resort to other solutions(eg. container) if they got bored by port conflict due to usages of TestingCluster and TestingServer.restart.

@kezhuw kezhuw force-pushed the CURATOR-535-fix-port-conflict-for-TestingServer branch 2 times, most recently from c82a8de to 16fd81a Compare June 22, 2022 03:51
Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

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

LGTM

@tisonkun
Copy link
Member

tisonkun commented Nov 8, 2022

@kezhuw sorry for the late review. I'm going to merge this patch if the conflict gets resolved. Would you continue this patch?

@kezhuw kezhuw force-pushed the CURATOR-535-fix-port-conflict-for-TestingServer branch from 16fd81a to 643c7b0 Compare February 5, 2023 06:59
Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

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

As we need to use reflection to access the ZK server internals, what about sending a path to ZooKeeper in order to allow us to do this stuff without reflection?
Otherwise there is a good chance that we won't be compatible with future ZooKeeper releases if they do some refactoring

@kezhuw
Copy link
Member Author

kezhuw commented Feb 5, 2023

@eolivelli I have created ZOOKEEPER-4670 for your point. It would be really nice to code without reflection. But I noticed that CURATOR-587(#434) did not require bumping of zookeeper dependency. If we are going to depend on ZOOKEEPER-4670 then clients will have to sync their zookeeper dependencies with curator. Is it ok for this ?

@kezhuw kezhuw force-pushed the CURATOR-535-fix-port-conflict-for-TestingServer branch from 643c7b0 to 8eda7d0 Compare February 5, 2023 13:24
@kezhuw
Copy link
Member Author

kezhuw commented Feb 15, 2023

I think I could drop most of reflection usages but with one exception. The reflection in ZooKeeperServerEmbeddedAdapter is mandatory due to ZOOKEEPER-4303(ZooKeeperServerEmbeddedImpl does not support bind to port 0 until apache/zookeeper#1868 which has not been released in any versions.)

@kezhuw kezhuw force-pushed the CURATOR-535-fix-port-conflict-for-TestingServer branch from 8eda7d0 to c3bb1a9 Compare February 20, 2023 02:09
@kezhuw
Copy link
Member Author

kezhuw commented Feb 20, 2023

@eolivelli I have dropped most reflection usages except ZooKeeperServerEmbeddedAdapter where I documented clearly its purpose(circumventing ZOOKEEPER-4303).

Alternative, I think we can wait until possible 3.7.2 with fix for ZOOKEEPER-4303.

Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

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

This even looks better !

@tisonkun @Randgalt @cammckenzie would you mind taking a look ?

@tisonkun tisonkun self-requested a review February 20, 2023 13:15
/**
* @deprecated use {@link TestingServer#getConnectString()} or {@link TestingCluster#getConnectString()} instead
*/
@Deprecated
Copy link
Member

Choose a reason for hiding this comment

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

If we already remove public QuorumPeerConfig getConfig() throws Exception { which breaks compatibility, what if we remove this deprecated mark and change the visibility to default (pacakge)?

Copy link
Member

Choose a reason for hiding this comment

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

... and why do we remove ZooKeeperMainFace#getConfig?

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, this pr mixed two things: CURATOR-535 and bring back TestTestingServer#setCustomTickTimeTest for #383.

ZooKeeperMainFace#getConfig was introduced in #434, and its sole external usage in TestTestingServer#setCustomTickTimeTest undermines #383.

Comparing to public InstanceSpec, I think ZooKeeperMainFace is more like an internal concept. May be we can restrict visibility of ZooKeeperMainFace to package ? This should solve all above concerns if make sense to you.

Copy link
Member

Choose a reason for hiding this comment

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

@kezhuw That sounds reasonable. And we can add getTickTime or something so that we don't have to change hasZooKeeperServerEmbedded.

Copy link
Member Author

Choose a reason for hiding this comment

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

I have removed public from ZooKeeperMainFace. @tisonkun

getTickTime needs reflection as ZooKeeperServerEmbedded exposes no such info(ZOOKEEPER-4670). In previous version(8eda7d0), I exposed a get method in ZooKeeperMainFace to retrieve ServerCnxnFactory where both getTickTime and getClientPort could be easily constructed . But that approach depends heavily on reflection as QuorumPeerMain and ZooKeeperServerEmbedded exposes no such info.

@tisonkun
Copy link
Member

The rest looks good. Comments above.

…t allocation

This commit tries to solve port conflict for `TestingServer` if port is
unspecified(aka. `port <= 0`):
* Set `InstanceSpec.port` to 0 if port is unspecified.
* Save OS chosen bind port after started to maintain same port across
  restart.

Ideally, it should be possible to bootstrap `TestingCluster`(with unspecified ports)
too with help from `reconfig`. But there are difficulties since election port, quorum
port were not designed to be bound to `0` in ZooKeeper. `TestingServer` should be
enough for most cases.

Users should resort to other solutions(eg. container) if they got bored
by port conflict due to usages of `TestingCluster` and
`TestingServer.restart`.
@kezhuw kezhuw force-pushed the CURATOR-535-fix-port-conflict-for-TestingServer branch from c3bb1a9 to 6348215 Compare February 21, 2023 08:34
Copy link
Member

@tisonkun tisonkun left a comment

Choose a reason for hiding this comment

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

LGTM. Further improvement can be investigated later.

@eolivelli eolivelli merged commit 7e7c207 into apache:master Feb 21, 2023
@eolivelli
Copy link
Contributor

@kezhuw I can't assign the JIRA issue to you, but I have committed the patch
thank you very much for your contribution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants