jackjlli commented on a change in pull request #4323: [Controller Separation] Add logic for lead controller resource URL: https://github.com/apache/incubator-pinot/pull/4323#discussion_r305043106
########## File path: pinot-core/src/main/java/org/apache/pinot/server/realtime/ControllerLeaderLocator.java ########## @@ -78,35 +82,81 @@ public static ControllerLeaderLocator getInstance() { /** * Locate the controller leader so that we can send LLC segment completion requests to it. * Checks the {@link ControllerLeaderLocator::_cachedControllerLeaderInvalid} flag and fetches the leader from helix if cached value is invalid - * + * @param rawTableName table name without type. * @return The host:port string of the current controller leader. */ - public synchronized Pair<String, Integer> getControllerLeader() { + public synchronized Pair<String, Integer> getControllerLeader(String rawTableName) { if (!_cachedControllerLeaderInvalid) { return _controllerLeaderHostPort; } + String leaderForTable = getLeaderForTable(rawTableName); + if (leaderForTable == null) { + LOGGER.warn("Failed to find a leader for Table: {}", rawTableName); + _cachedControllerLeaderInvalid = true; + return null; + } else { + _controllerLeaderHostPort = generateControllerLeaderHostPortPair(leaderForTable); + _cachedControllerLeaderInvalid = false; + LOGGER.info("Setting controller leader to be {}:{}", _controllerLeaderHostPort.getFirst(), + _controllerLeaderHostPort.getSecond()); + return _controllerLeaderHostPort; + } + } + + /** + * If partition leader exists, use this as the leader for realtime segment completion. + * Otherwise, try to use Helix leader. + * @param rawTableName table name without type + * @return the controller leader id with hostname and port for this table, e.g. localhost_9000 + */ + private String getLeaderForTable(String rawTableName) { + String leaderForTable; + ExternalView leadControllerResourceExternalView = + _helixManager.getClusterManagmentTool().getResourceExternalView(_clusterName, LEAD_CONTROLLER_RESOURCE_NAME); + String partitionLeader = + LeadControllerUtils.getLeadControllerForTable(leadControllerResourceExternalView, rawTableName); + if (partitionLeader != null) { + // Converts participant id (with Prefix "Controller_") to controller id and assigns it as the leader. + leaderForTable = LeadControllerUtils.extractLeadControllerHostNameAndPort(partitionLeader); + } else { + // Gets Helix leader to be the leader to this table, otherwise returns null. + leaderForTable = getHelixClusterLeader(); + } + return leaderForTable; + } + + /** + * Gets Helix leader in the cluster. Null if there is no leader. + * @return Helix leader. Review comment: Done. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org