Skip to content

Commit

Permalink
Fix maxInstances error (#332)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Graband <sgraband@eclipsesource.com>
  • Loading branch information
jfaltermeier and sgraband authored Jul 23, 2024
1 parent 3563ca9 commit 2459880
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ public static String readResourceAndReplacePlaceholders(String resourceName, Map
try (InputStream inputStream = getInputStream(resourceName, correlationId)) {
String template = new BufferedReader(new InputStreamReader(inputStream)).lines().parallel()
.collect(Collectors.joining("\n"));
LOGGER.trace(formatLogMessage(correlationId, "Replacing placeholders. Starting template:\n" + template));
for (Entry<String, String> replacement : replacements.entrySet()) {
String value = replacement.getValue() != null ? replacement.getValue() : "";
template = template.replace(replacement.getKey(), value);
LOGGER.trace(formatLogMessage(correlationId,
"Replaced " + replacement.getKey() + " with " + value + " :\n" + template));
LOGGER.trace(formatLogMessage(correlationId, "Replaced " + replacement.getKey() + " with " + value));
}
LOGGER.trace(formatLogMessage(correlationId, "Replacement finished. Result:\n" + template));
return template;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.theia.cloud.common.k8s.resource.OperatorStatus;
import org.eclipse.theia.cloud.common.k8s.resource.appdefinition.AppDefinitionSpec;
import org.eclipse.theia.cloud.common.k8s.resource.session.Session;
import org.eclipse.theia.cloud.common.k8s.resource.session.SessionSpec;
Expand All @@ -41,7 +42,7 @@ public static boolean checkIfMaxInstancesReached(NamespacedKubernetesClient clie

if (appDefinitionSpec.getMaxInstances() == null || appDefinitionSpec.getMaxInstances() < 0) {
LOGGER.debug(formatLogMessage(correlationId,
"App Definition " + appDefinitionSpec.getName() + " allows indefinite sessions."));
"App Definition " + appDefinitionSpec.getName() + " allows infinite sessions."));
return false;
}

Expand All @@ -56,9 +57,12 @@ public static boolean checkIfMaxInstancesReached(NamespacedKubernetesClient clie
.list().getItems().stream()//
.filter(w -> {
String sessionAppDefinition = w.getSpec().getAppDefinition();
boolean result = appDefinitionName.equals(sessionAppDefinition);
LOGGER.trace(formatLogMessage(correlationId, "Counting instances of app definition "
+ appDefinitionSpec.getName() + ": Is " + w.getSpec() + " of app definition? " + result));
// Errored resources should not be counted
boolean result = appDefinitionName.equals(sessionAppDefinition)
&& !OperatorStatus.ERROR.equals(w.getStatus().getOperatorStatus());
LOGGER.trace(formatLogMessage(correlationId,
"Counting handled instances of app definition " + appDefinitionSpec.getName() + ": Is "
+ w.getSpec() + " of app definition and handled? " + result));
return result;
})//
.count();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import org.eclipse.theia.cloud.common.k8s.client.DefaultTheiaCloudClient;
import org.eclipse.theia.cloud.common.k8s.client.TheiaCloudClient;
import org.eclipse.theia.cloud.common.k8s.resource.appdefinition.AppDefinition;
import org.eclipse.theia.cloud.common.k8s.resource.session.Session;
import org.eclipse.theia.cloud.common.k8s.resource.session.SessionSpec;
import org.eclipse.theia.cloud.common.k8s.resource.session.SessionStatus;
Expand All @@ -33,6 +34,7 @@
import org.eclipse.theia.cloud.common.util.CustomResourceUtil;
import org.eclipse.theia.cloud.service.session.SessionPerformance;
import org.eclipse.theia.cloud.service.workspace.UserWorkspace;
import org.jboss.logging.Logger;

import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.EnvVar;
Expand All @@ -48,7 +50,9 @@
@ApplicationScoped
public final class K8sUtil {
private NamespacedKubernetesClient KUBERNETES = CustomResourceUtil.createClient();
private TheiaCloudClient CLIENT = new DefaultTheiaCloudClient(KUBERNETES);
public TheiaCloudClient CLIENT = new DefaultTheiaCloudClient(KUBERNETES);

protected final Logger logger = Logger.getLogger(getClass());

public Workspace createWorkspace(String correlationId, UserWorkspace data) {
WorkspaceSpec spec = new WorkspaceSpec(data.name, data.label, data.appDefinition, data.user);
Expand Down Expand Up @@ -178,15 +182,34 @@ private boolean isPodFromSession(Pod pod, Session session) {
}
Container container = optionalContainer.get();
Optional<EnvVar> optionalEnv = container.getEnv().stream()
.filter(env -> env.getName().equals("THEIA_CLOUD_SESSION_NAME")).findFirst();
.filter(env -> env.getName().equals("THEIACLOUD_SESSION_NAME")).findFirst();
if (optionalEnv.isEmpty()) {
return false;
}
EnvVar env = optionalEnv.get();
return env.getValue().equals(session.getSpec().getName()) ? true : false;
return env.getValue().equals(session.getSpec().getName());
}

public boolean hasAppDefinition(String appDefinition) {
return CLIENT.appDefinitions().get(appDefinition).isPresent();
}

public boolean isMaxInstancesReached(String appDefString) {
Optional<AppDefinition> optAppDef = CLIENT.appDefinitions().get(appDefString);
if (!optAppDef.isPresent()) {
return true; // appDef does not exist, so we already reached the maximum number of instances
}
AppDefinition appDef = optAppDef.get();
if (appDef.getSpec().getMaxInstances() == null) {
return false; // max instances is not set, so we do not have a limit
}
long maxInstances = appDef.getSpec().getMaxInstances();
if (maxInstances < 0) {
return false; // max instances is set to negative, so we can ignore it
}
long podsOfAppDef = CLIENT.sessions().list().stream() // All sessions
.filter(s -> s.getSpec().getAppDefinition().equals(appDefString)) // That are from the appDefinition
.filter(s -> getPodForSession(s).isPresent()).count(); // That already have a pod
return podsOfAppDef >= maxInstances;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ public String launch(LaunchRequest request) {
throw new TheiaCloudWebException(TheiaCloudError.INVALID_APP_DEFINITION_NAME);
}

if (k8sUtil.isMaxInstancesReached(request.appDefinition)) {
error(correlationId, "Failed to launch session. App Definition '" + request.appDefinition
+ "' has max instances reached.");
throw new TheiaCloudWebException(TheiaCloudError.SESSION_SERVER_LIMIT_REACHED);
}

if (request.isEphemeral()) {
info(correlationId, "Launching ephemeral session " + request);
return k8sUtil.launchEphemeralSession(correlationId, request.appDefinition, user, request.timeout,
Expand Down

0 comments on commit 2459880

Please sign in to comment.