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-551] Fix Handle Holder new connection string #345

Merged

Conversation

Randgalt
Copy link
Member

@Randgalt Randgalt commented Feb 3, 2020

Commit 26364c6 (Sat Sep 26 13:13:02 2015) changed HandleHolder.getNewConnectionString() was changed to return the new connection string instead of just a boolean. I believe the value returned should have been ensembleProvider.getConnectionString() not helper.getConnectionString(). TBH I no longer remember the genesis of this change but I can't make the current implementation make sense.

Additionally, a change was made to optionally call zooKeeper.updateServerList(). When this path is taken the handle holder's connection needs to be updated as well or we'll get an infinite loop of changes. The path that runs when ensembleProvider.updateServerListEnabled() is false ends up setting handle holder's connection to ensembleProvider.getConnectionString().

I'm loathe to make such low level changes in code that's existed for a long time. But, my investigation shows that this is how it should be. Hopefully, users can do testing.

Verified

This commit was signed with the committer’s verified signature.
jbedard Jason Bedard
Commit 26364c6 (Sat Sep 26 13:13:02 2015) changed HandleHolder.getNewConnectionString() was changed to return the new connection string instead of just a boolean. I believe the value returned should have been ensembleProvider.getConnectionString() not helper.getConnectionString(). TBH I no longer remember the genesis of this change but I can't make the current implementation make sense.

Additionally, a change was made to optionally call zooKeeper.updateServerList(). When this path is taken the handle holder's connection needs to be updated as well or we'll get an infinite loop of changes. The path that runs when ensembleProvider.updateServerListEnabled() is false ends up setting handle holder's connection to ensembleProvider.getConnectionString().

I'm loathe to make such low level changes in code that's existed for a long time. But, my investigation shows that this is how it should be. Hopefully, users can do testing.
@@ -48,7 +48,7 @@
private static final int MAX_BACKGROUND_EXCEPTIONS = 10;
private static final boolean LOG_EVENTS = Boolean.getBoolean(DebugUtils.PROPERTY_LOG_EVENTS);
private static final Logger log = LoggerFactory.getLogger(ConnectionState.class);
private final HandleHolder zooKeeper;
private final HandleHolder handleHolder;
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: renamed for clarity

@@ -34,15 +34,6 @@

private volatile Helper helper;

private interface Helper
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved to a top level class so imp can be shared and it's easier to read.

@@ -70,7 +61,16 @@ String getConnectionString()
String getNewConnectionString()
{
String helperConnectionString = (helper != null) ? helper.getConnectionString() : null;
return ((helperConnectionString != null) && !ensembleProvider.getConnectionString().equals(helperConnectionString)) ? helperConnectionString : null;
String ensembleProviderConnectionString = ensembleProvider.getConnectionString();
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: this is the major change

Copy link
Contributor

Choose a reason for hiding this comment

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

I have a question. helper is null until closeAndReset() is called, and new connection string can be sensed only if helper is not null. Isn't it possible to have new connection string (from the EnsembleTracker) before closeAndReset() was ever called? If it is possible, then it seems like the new connection string won't be handled, since helper would be null.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks @shayshim I'll look into this possiblity

Copy link
Contributor

Choose a reason for hiding this comment

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

The whole flow of how things interact is very confusing, but I don't think that this is an issue. closeAndReset() gets called from ConnectionState.reset() which gets called from the ConnectionState.start() method. I'm not 100% sure there's not a race condition here, but from what I can see, it seems improbable.

Copy link
Member Author

Choose a reason for hiding this comment

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

whole flow of how things interact is very confusing

Too true. What do we do? Should we attempt a more aggressive change?

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should just merge this change and look at cleaning up this stuff in a future PR? I think it would be a pretty significant change.

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'm OK with that. @shayshim ? Maybe you can both approve this PR when you're OK

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 a question. helper is null until closeAndReset() is called, and new connection string can be sensed only if helper is not null. Isn't it possible to have new connection string (from the EnsembleTracker) before closeAndReset() was ever called? If it is possible, then it seems like the new connection string won't be handled, since helper would be null.

closeAndReset() will cause ensembleProvider.getConnectionString() to get called anyway. Does that answer your question? I think the intent of the above code is to force-close the connection when there's a new connection string.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm OK with that. @shayshim ? Maybe you can both approve this PR when you're OK

I agree - better to continue refactor in different PR, dedicated for that

Copy link
Contributor

@shayshim shayshim Feb 12, 2020

Choose a reason for hiding this comment

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

closeAndReset() will cause ensembleProvider.getConnectionString() to get called anyway. Does that answer your question? I think the intent of the above code is to force-close the connection when there's a new connection string.

In short I wanted to make sure that closeAndReset() (create helper) is called before any new connection string is set .
As @cammckenzie said, it is called from ConnectionState.start(), which is called (eventually) from CuratorFrameworkImpl.start(), from line 338 using client.start() - before ensembleTracker.start() in line 353, which allows to set new connection strings.
So any call to getNewConnectionString(), with actual new connection string, will meet non null helper.
In addition to that, helper.getZooKeeper() is also called eventually from 338, so data.connectionString is set as needed, before getNewConnectionString() can be called.
So I think we have no issue here.

@@ -356,6 +356,7 @@ private void handleNewConnectionString(String newConnectionString)
if ( ensembleProvider.updateServerListEnabled() )
{
zooKeeper.updateServerList(newConnectionString);
handleHolder.resetConnectionString(newConnectionString);
Copy link
Member Author

Choose a reason for hiding this comment

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

Also here - this is the meat of the change

Copy link
Contributor

@shayshim shayshim left a comment

Choose a reason for hiding this comment

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

@Randgalt looks fine to me

Copy link
Contributor

@cammckenzie cammckenzie left a comment

Choose a reason for hiding this comment

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

Looks OK to me.

@Randgalt Randgalt requested a review from shayshim February 11, 2020 23:54
Copy link
Contributor

@shayshim shayshim left a comment

Choose a reason for hiding this comment

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

LGTM

@Randgalt Randgalt merged commit 75226fb into master Feb 12, 2020
bobningx pushed a commit to bobningx/curator that referenced this pull request Sep 17, 2020
Commit 26364c6 (Sat Sep 26 13:13:02 2015) changed HandleHolder.getNewConnectionString() was changed to return the new connection string instead of just a boolean. I believe the value returned should have been ensembleProvider.getConnectionString() not helper.getConnectionString(). TBH I no longer remember the genesis of this change but I can't make the current implementation make sense.

Additionally, a change was made to optionally call zooKeeper.updateServerList(). When this path is taken the handle holder's connection needs to be updated as well or we'll get an infinite loop of changes. The path that runs when ensembleProvider.updateServerListEnabled() is false ends up setting handle holder's connection to ensembleProvider.getConnectionString().

I'm loathe to make such low level changes in code that's existed for a long time. But, my investigation shows that this is how it should be. Hopefully, users can do testing.
@tisonkun tisonkun deleted the CURATOR-551-fix-handle-holder-new-connection-string branch March 13, 2023 07:30
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.

None yet

3 participants