-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[CURATOR-551] Fix Handle Holder new connection string #345
Conversation
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; |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
isnull
untilcloseAndReset()
is called, and new connection string can be sensed only ifhelper
is notnull
. Isn't it possible to have new connection string (from theEnsembleTracker
) beforecloseAndReset()
was ever called? If it is possible, then it seems like the new connection string won't be handled, sincehelper
would benull
.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
closeAndReset()
will causeensembleProvider.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); |
There was a problem hiding this comment.
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
There was a problem hiding this 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
There was a problem hiding this 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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.
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.