Skip to content
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

optionally limit reloads based on worker count #175

Merged
merged 10 commits into from
Apr 26, 2016
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ public class LoadBalancerConfiguration {
@NotNull
private Set<String> domains = Collections.emptySet();

@NotNull
@Min(1)
private int maxLbWorkerCount = 1;

@NotNull
private Optional<String> workerCountCommand = Optional.absent();

public String getName() {
return name;
}
Expand Down Expand Up @@ -99,4 +106,20 @@ public Set<String> getDomains() {
public void setDomains(Set<String> domains) {
this.domains = domains;
}

public int getMaxLbWorkerCount() {
return maxLbWorkerCount;
}

public void setMaxLbWorkerCount(int maxLbWorkerCount) {
this.maxLbWorkerCount = maxLbWorkerCount;
}

public Optional<String> getWorkerCountCommand() {
return workerCountCommand;
}

public void setWorkerCountCommand(Optional<String> workerCountCommand) {
this.workerCountCommand = workerCountCommand;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import com.hubspot.baragon.exceptions.LbAdapterExecuteException;
import com.hubspot.baragon.exceptions.LockTimeoutException;
import com.hubspot.baragon.exceptions.MissingTemplateException;
import com.hubspot.baragon.models.BaragonAgentMetadata;
import com.hubspot.baragon.models.BaragonConfigFile;
import com.hubspot.baragon.models.BaragonService;
import com.hubspot.baragon.models.ServiceContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.hubspot.baragon.agent.lbs;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
Expand All @@ -13,11 +18,13 @@

import com.codahale.metrics.annotation.Timed;
import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.hubspot.baragon.agent.config.LoadBalancerConfiguration;
import com.hubspot.baragon.exceptions.InvalidConfigException;
import com.hubspot.baragon.exceptions.LbAdapterExecuteException;
import com.hubspot.baragon.exceptions.WorkerLimitReachedException;

@Singleton
public class LocalLbAdapter {
Expand All @@ -44,6 +51,29 @@ private int executeWithTimeout(CommandLine command, int timeout) throws LbAdapte
}
}

private Optional<Integer> getOutputAsInt(String command) {
try {
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();

try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));) {
List<String> output = new ArrayList<>();
String line = br.readLine();
while (line != null) {
output.add(line);
line = br.readLine();
}
return Optional.of(Integer.parseInt(output.get(0).trim()));
} catch (Exception e) {
LOG.error("Could not get worker count from command {}", command, e);
return Optional.absent();
}
} catch (IOException ioe) {
LOG.error("Could not get worker count from command {}", command, ioe);
return Optional.absent();
}
}

@Timed
public void checkConfigs() throws InvalidConfigException {
try {
Expand All @@ -58,9 +88,20 @@ public void checkConfigs() throws InvalidConfigException {
}

@Timed
public void reloadConfigs() throws LbAdapterExecuteException, IOException {
public void reloadConfigs() throws LbAdapterExecuteException, IOException, WorkerLimitReachedException {
if (loadBalancerConfiguration.getWorkerCountCommand().isPresent()) {
checkWorkerCount();
}
final long start = System.currentTimeMillis();
final int exitCode = executeWithTimeout(CommandLine.parse(loadBalancerConfiguration.getReloadConfigCommand()), loadBalancerConfiguration.getCommandTimeoutMs());
LOG.info("Reloaded configs via '{}' in {}ms (exit code = {})", loadBalancerConfiguration.getReloadConfigCommand(), System.currentTimeMillis() - start, exitCode);
}

private void checkWorkerCount() throws WorkerLimitReachedException {
Optional<Integer> workerCount = getOutputAsInt(loadBalancerConfiguration.getWorkerCountCommand().get());
LOG.debug("Current worker count: {}", workerCount);
if (!workerCount.isPresent() || workerCount.get() > loadBalancerConfiguration.getMaxLbWorkerCount()) {
throw new WorkerLimitReachedException(String.format("%s LB workers currently running, wait for old workers to exit before attempting to reload configs", workerCount.get()));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.hubspot.baragon.exceptions;

public class WorkerLimitReachedException extends Exception {
public WorkerLimitReachedException(String message) {
super(message);
}
}