private Map<String, String> queryExhibitors(Exhibitors localExhibitors) { Map<String, String> values = newValues(); long start = System.currentTimeMillis(); int retries = 0; boolean done = false; while (!done) { List<String> hostnames = Lists.newArrayList(localExhibitors.getHostnames()); if (hostnames.size() == 0) { done = true; } else { String hostname = hostnames.get(random.nextInt(hostnames.size())); try { String encoded = restClient.getRaw(hostname, localExhibitors.getRestPort(), restUriPath, MIME_TYPE); values.putAll(decodeExhibitorList(encoded)); done = true; } catch (Throwable e) { if (retryPolicy.allowRetry( retries++, System.currentTimeMillis() - start, RetryLoop.getDefaultRetrySleeper())) { log.warn("Couldn't get servers from Exhibitor. Retrying.", e); } else { log.error("Couldn't get servers from Exhibitor. Giving up.", e); done = true; } } } } return values; }
@VisibleForTesting protected void poll() { Exhibitors localExhibitors = exhibitors.get(); Map<String, String> values = queryExhibitors(localExhibitors); int count = getCountFromValues(values); if (count == 0) { log.warn("0 count returned from Exhibitors. Using backup connection values."); values = useBackup(localExhibitors); count = getCountFromValues(values); } if (count > 0) { int port = Integer.parseInt(values.get(VALUE_PORT)); StringBuilder newConnectionString = new StringBuilder(); List<String> newHostnames = Lists.newArrayList(); for (int i = 0; i < count; ++i) { if (newConnectionString.length() > 0) { newConnectionString.append(","); } String server = values.get(VALUE_SERVER_PREFIX + i); newConnectionString.append(server).append(":").append(port); newHostnames.add(server); } String newConnectionStringValue = newConnectionString.toString(); if (!newConnectionStringValue.equals(connectionString.get())) { log.info( "Connection string has changed. Old value (%s), new value (%s)", connectionString.get(), newConnectionStringValue); } Exhibitors newExhibitors = new Exhibitors( newHostnames, localExhibitors.getRestPort(), new Exhibitors.BackupConnectionStringProvider() { @Override public String getBackupConnectionString() throws Exception { return masterExhibitors .get() .getBackupConnectionString(); // this may be overloaded by clients. Make sure // there is always a method call to get the // value. } }); connectionString.set(newConnectionStringValue); exhibitors.set(newExhibitors); } }