-
Notifications
You must be signed in to change notification settings - Fork 6
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
Do not merge: Add ip node spec #6
base: master
Are you sure you want to change the base?
Conversation
val clusterStateNodeList = if (allowOfflineReferences) allNodes else liveNodes | ||
|
||
//First try by matching to the fully qualified domain name | ||
val dnsNodeList: Map[String, String] = dnsNameMap(clusterStateNodeList) |
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.
Couldn't think of an idiomatic way to implement this without refactoring each individual filter into a method and use case classes
*/ | ||
def unambiguousFragment(fragment: String, nodeComparisonMap: Map[String,String]): Option[String] = { | ||
findUnambigousNode(nodeComparisonMap, (s: String) => s == fragment) | ||
.orElse(findUnambigousNode(nodeComparisonMap, (s: String) => s.contains(fragment))) |
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 think we should get rid of the .contains, it prohibits exact IP/Hostname specification. I believe this happens with the existing version of solr cloud manager also.
For e.g specifying --nodes 1.0.0.8 selects nodes 1.0.0.8,1.0.0.81 and 1.0.0.82
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 agree "contains" is a poor choice for partial name matching. I liked the idea of being able to say --nodes foo2,foo3
or perhaps --nodes 0.8,0.81,0.82
instead of repeating all the identical fully qualified info every time though, and I wasn't too bothered by 1.0.0.8 matching 1.0.0.8 and 1.0.0.81 because if I do actually have both, it should throw the ambiguous node spec message with the conflicting possibilities.
Perhaps a smarter comparison would do literal matches, but within the context of period-separated chunks. Again, just looking to see if there's a single node that matches while using that comparison function.
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.
So the ambiguous node exception will not be thrown every time, IMO it should be. For e.g. if you invoke waitactive with an IP that matches multiple nodes, the call just sums up the replica count across those nodes and returns their state e.g. "All 18 shards were active". IMO we should enforce really tight matching in this case.
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.
So I think this is starting to get concealed by the current implementation details, but at a high level, the purpose of this code is to try to find one or more nodes that match a string, according to a sequence of (increasingly fuzzy) comparisons.
For situations where the string is expected to allow matching of multiple nodes ("all", "regex", etc), you work through a list of comparison approaches until one finds non-zero matches, then stop running comparisons and use those. Error if the final result is an empty list.
For situations where the string is expected to match a single node, you try comparison approaches until one gives you exactly one node, then you stop running comparisons and use that. Error if the final result size != 1. (maybe accumulate any ambiguous results for the error message)
@@ -87,34 +88,85 @@ case class SolrState(state: ClusterState, collectionInfo: CollectionInfo, config | |||
lazy val activeReplicas = allReplicas.filter(_.active) | |||
lazy val inactiveReplicas = allReplicas.filterNot(activeReplicas.contains) | |||
|
|||
/** | |||
* Returns all replicas for a given collection |
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.
This comment doesn't tell me anything that isn't in the function name.
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.
Removing
def replicasFor(collection: String): Seq[SolrReplica] = allReplicas.filter(_.collection == collection) | ||
|
||
/** | ||
* Returns all replicas for a given collection, slice combination |
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.
Same.
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.
Removing
case i => | ||
//If a comma separated list of nodes is specified, then for each node |
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 find this comment misleading, as in this context, we're evaluating a single indicator. There's no list.
case i => | ||
//If a comma separated list of nodes is specified, then for each node | ||
val nodeName = Try(Seq(canonicalNodeName(i, allowOfflineReferences))).recover({ |
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.
But on a related note, maybe the Seq
wrapper here is confusing and could be removed.
*/ | ||
def unambiguousFragment(fragment: String, nodeComparisonMap: Map[String,String]): Option[String] = { | ||
findUnambigousNode(nodeComparisonMap, (s: String) => s == fragment) | ||
.orElse(findUnambigousNode(nodeComparisonMap, (s: String) => s.contains(fragment))) |
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 agree "contains" is a poor choice for partial name matching. I liked the idea of being able to say --nodes foo2,foo3
or perhaps --nodes 0.8,0.81,0.82
instead of repeating all the identical fully qualified info every time though, and I wasn't too bothered by 1.0.0.8 matching 1.0.0.8 and 1.0.0.81 because if I do actually have both, it should throw the ambiguous node spec message with the conflicting possibilities.
Perhaps a smarter comparison would do literal matches, but within the context of period-separated chunks. Again, just looking to see if there's a single node that matches while using that comparison function.
* @param comparison function to use for comparison | ||
* @return | ||
*/ | ||
def findUnambigousNode(nodeComparisonMap: Map[String,String], comparison: (String) => Boolean): Option[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.
Maybe this should be changed to just return the matching node list, and have the test for "single-match" elsewhere. Then we can reuse it in the regex side of things too.
IMO, the comparisons should be fuzzy only when the user passes in regular expressions. When using the "--nodes" argument to specify nodes, the expectation should be that his "indicator" match one node only. These indicators could be the exact host name or IP (circumventing the problem of an indicator matching multiple nodes). The changes I've made in this PR enable the user to pass in specific IPs as well (ipNameMap). I'd like to remove the contains altogether and enforce the condition that one indicator match one node only (this happens only in one specific case atm) |
"For situations where the string is expected to match a single node, you try comparison approaches until one gives you exactly one node, then you stop running comparisons and use that. Error if the final result size != 1. (maybe accumulate any ambiguous results for the error message)" The getNodeListUsingRegEx uses a similar multi-phase approach |
…nd to determine success
Initial pull request for evaluation and discussion