-
Notifications
You must be signed in to change notification settings - Fork 146
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
support multiple master candidates #352
Conversation
this is to support multiple master api urls when start the framework, support multiple mesos api urls failover in attempts. And does not break current c.url logic. |
related #339 |
@jdef would you like to take a look when you get a chance? |
@tsenart @vladimirvivien @jdef any ideas? does this repo still in maintaining? seems it has been a long time after this pr was created. |
Thanks for the PR! This repo is maintained, and I'm basically the only maintainer at this point .. so sometimes it takes me while to get around to reviewing PRs. Thanks for being patient. It looks like the use case you're trying to address is this:
Does that sound about right? These candidates are more like "bootstrap" endpoints, right? Because in a cloudy environment where servers come and go, it's possible that the initial nodes might cycle out (unless you were using floating IPs that remaining the same across recycled instances). I'm interested in the specifics if your use case. Please elaborate in the PR description. |
@jdef Thanks for looking at this pr, and the items you listed in the comment above are pretty much correct!
In our case, we choose to use mesos masters raw ip/dns directly (akka. candidates in this pr), we are aware of mesos master addresses could be changed totally, but in a high availability, fault tolerant mesos scheduler, the active/standby schedulers could easily rolling restart to load the latest mesos master candidates in case. So we propose another candidates option in this pr to initiate the mesos framework, which is not breaking origin single url register way, to let developer make the choice according to their use case. |
OK. Let me then suggest the following changes to this PR:
|
e.g. type CandidateSelector func() string
func FixedCandidateSelector(s []string) CandidateSelector { ... } // cycles over s |
@jdef fair enough, i've changed the pr according to your comments. an example might be as follows:
|
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 for the changes, left a few more comments.
var candidate string | ||
if !ok { | ||
if cli.candidateSelector == nil { | ||
log.Printf("not found candidate selector, using url when initilize framework") |
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.
please wrap calls to log.XXX
with an if debug
check
candidate = cli.candidateSelector() | ||
} | ||
if candidate == "" { | ||
log.Printf("not found candidate url, return directly") |
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.
ditto
return | ||
} | ||
} else { | ||
candidate = redirectErr.newURL |
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 make this the default value of candidate
when it's initially declared and get rid of this else
statement
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.
get newURL from redirectErr object is only safe when the ok == null. (otherwise there will be some nil point error in case)
this else block seems is necessary at here
@@ -74,6 +75,8 @@ type ( | |||
requestOpts []httpcli.RequestOpt // requestOpts are temporary per-request options | |||
opt httpcli.Opt // opt is a temporary client option | |||
} | |||
|
|||
CandidateSelector func() 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.
yes, please add at least a one-line doc string for this. something like:
// CandidateSelector returns the next endpoint to try if there are errors reaching the mesos master, or else an empty string if there are no such candidates.
@@ -134,6 +137,14 @@ func AllowReconnection(v bool) Option { | |||
} | |||
} | |||
|
|||
func MasterCandidates(cs CandidateSelector) Option { |
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.
nit: maybe rename to EndpointCandidates
for clarity (since it's actually selecting the next endpoint for the http client)
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
My last wish is that there would be a unit test for this logic, which would probably be easiest if most of the new code was moved to a helper func that produced the next endpoint to use (because the unit test could focus on testing the complicated logic that's being introduced by this PR).
If needed, the unit test could be added in a follow-up PR.
great, after upstream this change, our prod system do not need to maintain a forked mesos-go repo for multiple candidates purpose in our organization. i will think of the unit test part in another pr. |
@huahuiyang please rebase so that I can merge this |
@jdef rebased. |
ping @jdef |
@jdef any chance for you to take a look and get this pr merged? thanks |
LGTM, thanks |
In this pr, if the mesos framework specify a candidate selector(could be dynamic func), the framework will gain the ability to failover across multiple mesos masters. otherwise, it will only rely on the url as an initial configuration.