Skip to content

Commit

Permalink
added custom spotless config (#28)
Browse files Browse the repository at this point in the history
* update

* rewrite if

* tj bot spotless config
  • Loading branch information
Taz03 authored May 23, 2024
1 parent fdea411 commit 584f0f9
Show file tree
Hide file tree
Showing 26 changed files with 711 additions and 503 deletions.
18 changes: 5 additions & 13 deletions JShellAPI/src/main/java/org/togetherjava/jshellapi/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,11 @@
import org.springframework.lang.Nullable;

@ConfigurationProperties("jshellapi")
public record Config(
long regularSessionTimeoutSeconds,
long oneTimeSessionTimeoutSeconds,
long evalTimeoutSeconds,
long evalTimeoutValidationLeeway,
int sysOutCharLimit,
long maxAliveSessions,
int dockerMaxRamMegaBytes,
double dockerCPUsUsage,
@Nullable String dockerCPUSetCPUs,
long schedulerSessionKillScanRateSeconds,
long dockerResponseTimeout,
long dockerConnectionTimeout) {
public record Config(long regularSessionTimeoutSeconds, long oneTimeSessionTimeoutSeconds,
long evalTimeoutSeconds, long evalTimeoutValidationLeeway, int sysOutCharLimit,
long maxAliveSessions, int dockerMaxRamMegaBytes, double dockerCPUsUsage,
@Nullable String dockerCPUSetCPUs, long schedulerSessionKillScanRateSeconds,
long dockerResponseTimeout, long dockerConnectionTimeout) {
public Config {
if (regularSessionTimeoutSeconds <= 0)
throw new IllegalArgumentException("Invalid value " + regularSessionTimeoutSeconds);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package org.togetherjava.jshellapi.dto;

public record JShellEvalAbortion(
String sourceCause, String remainingSource, JShellEvalAbortionCause cause) {}
public record JShellEvalAbortion(String sourceCause, String remainingSource,
JShellEvalAbortionCause cause) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@
public sealed interface JShellEvalAbortionCause {

@JsonTypeName("TIMEOUT")
record TimeoutAbortionCause() implements JShellEvalAbortionCause {}
record TimeoutAbortionCause() implements JShellEvalAbortionCause {
}

@JsonTypeName("UNCAUGHT_EXCEPTION")
record UnhandledExceptionAbortionCause(String exceptionClass, String exceptionMessage)
implements JShellEvalAbortionCause {}
record UnhandledExceptionAbortionCause(String exceptionClass,
String exceptionMessage) implements JShellEvalAbortionCause {
}

@JsonTypeName("COMPILE_TIME_ERROR")
record CompileTimeErrorAbortionCause(List<String> errors) implements JShellEvalAbortionCause {}
record CompileTimeErrorAbortionCause(List<String> errors) implements JShellEvalAbortionCause {
}

@JsonTypeName("SYNTAX_ERROR")
record SyntaxErrorAbortionCause() implements JShellEvalAbortionCause {}
record SyntaxErrorAbortionCause() implements JShellEvalAbortionCause {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@

import java.util.List;

public record JShellResult(
List<JShellSnippetResult> snippetsResults,
@Nullable JShellEvalAbortion abortion,
boolean stdoutOverflow,
String stdout) {
public record JShellResult(List<JShellSnippetResult> snippetsResults,
@Nullable JShellEvalAbortion abortion, boolean stdoutOverflow, String stdout) {
public JShellResult {
snippetsResults = List.copyOf(snippetsResults);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package org.togetherjava.jshellapi.dto;

public record JShellResultWithId(String id, JShellResult result) {}
public record JShellResultWithId(String id, JShellResult result) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

import org.springframework.lang.Nullable;

public record JShellSnippetResult(
SnippetStatus status, SnippetType type, int id, String source, @Nullable String result) {}
public record JShellSnippetResult(SnippetStatus status, SnippetType type, int id, String source,
@Nullable String result) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ public DockerException(Throwable cause) {
super(cause);
}

public DockerException(
String message,
Throwable cause,
boolean enableSuppression,
public DockerException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import org.togetherjava.jshellapi.dto.JShellResult;
import org.togetherjava.jshellapi.dto.JShellResultWithId;
import org.togetherjava.jshellapi.exceptions.DockerException;
Expand All @@ -21,64 +22,45 @@ public class JShellController {
private StartupScriptsService startupScriptsService;

@PostMapping("/eval/{id}")
public JShellResult eval(
@PathVariable String id,
public JShellResult eval(@PathVariable String id,
@RequestParam(required = false) StartupScriptId startupScriptId,
@RequestBody String code)
throws DockerException {
@RequestBody String code) throws DockerException {
validateId(id);
return service.session(id, startupScriptId)
.eval(code)
.orElseThrow(
() ->
new ResponseStatusException(
HttpStatus.CONFLICT, "An operation is already running"));
.eval(code)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.CONFLICT,
"An operation is already running"));
}

@PostMapping("/eval")
public JShellResultWithId eval(
@RequestParam(required = false) StartupScriptId startupScriptId,
@RequestBody String code)
throws DockerException {
public JShellResultWithId eval(@RequestParam(required = false) StartupScriptId startupScriptId,
@RequestBody String code) throws DockerException {
JShellService jShellService = service.session(startupScriptId);
return new JShellResultWithId(
jShellService.id(),
jShellService
.eval(code)
.orElseThrow(
() ->
new ResponseStatusException(
HttpStatus.CONFLICT,
"An operation is already running")));
return new JShellResultWithId(jShellService.id(),
jShellService.eval(code)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.CONFLICT,
"An operation is already running")));
}

@PostMapping("/single-eval")
public JShellResult singleEval(
@RequestParam(required = false) StartupScriptId startupScriptId,
@RequestBody String code)
throws DockerException {
public JShellResult singleEval(@RequestParam(required = false) StartupScriptId startupScriptId,
@RequestBody String code) throws DockerException {
JShellService jShellService = service.oneTimeSession(startupScriptId);
return jShellService
.eval(code)
.orElseThrow(
() ->
new ResponseStatusException(
HttpStatus.CONFLICT, "An operation is already running"));
return jShellService.eval(code)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.CONFLICT,
"An operation is already running"));
}

@GetMapping("/snippets/{id}")
public List<String> snippets(
@PathVariable String id, @RequestParam(required = false) boolean includeStartupScript)
throws DockerException {
public List<String> snippets(@PathVariable String id,
@RequestParam(required = false) boolean includeStartupScript) throws DockerException {
validateId(id);
if (!service.hasSession(id))
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Id " + id + " not found");
return service.session(id, null)
.snippets(includeStartupScript)
.orElseThrow(
() ->
new ResponseStatusException(
HttpStatus.CONFLICT, "An operation is already running"));
.snippets(includeStartupScript)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.CONFLICT,
"An operation is already running"));
}

@DeleteMapping("/{id}")
Expand Down Expand Up @@ -106,8 +88,7 @@ public void setStartupScriptsService(StartupScriptsService startupScriptsService

private static void validateId(String id) throws ResponseStatusException {
if (!id.matches("[a-zA-Z0-9][a-zA-Z0-9_.-]+")) {
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST,
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"Id " + id + " doesn't match the regex [a-zA-Z0-9][a-zA-Z0-9_.-]+");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import org.togetherjava.jshellapi.Config;

import java.io.*;
Expand All @@ -33,20 +33,20 @@ public DockerService(Config config) {
DefaultDockerClientConfig clientConfig =
DefaultDockerClientConfig.createDefaultConfigBuilder().build();
ApacheDockerHttpClient httpClient =
new ApacheDockerHttpClient.Builder()
.dockerHost(clientConfig.getDockerHost())
.sslConfig(clientConfig.getSSLConfig())
.responseTimeout(Duration.ofSeconds(config.dockerResponseTimeout()))
.connectionTimeout(Duration.ofSeconds(config.dockerConnectionTimeout()))
.build();
new ApacheDockerHttpClient.Builder().dockerHost(clientConfig.getDockerHost())
.sslConfig(clientConfig.getSSLConfig())
.responseTimeout(Duration.ofSeconds(config.dockerResponseTimeout()))
.connectionTimeout(Duration.ofSeconds(config.dockerConnectionTimeout()))
.build();
this.client = DockerClientImpl.getInstance(clientConfig, httpClient);

cleanupLeftovers(WORKER_UNIQUE_ID);
}

private void cleanupLeftovers(UUID currentId) {
for (Container container :
client.listContainersCmd().withLabelFilter(Set.of(WORKER_LABEL)).exec()) {
for (Container container : client.listContainersCmd()
.withLabelFilter(Set.of(WORKER_LABEL))
.exec()) {
String containerHumanName =
container.getId() + " " + Arrays.toString(container.getNames());
LOGGER.info("Found worker container '{}'", containerHumanName);
Expand All @@ -57,50 +57,44 @@ private void cleanupLeftovers(UUID currentId) {
}
}

public String spawnContainer(
long maxMemoryMegs,
long cpus,
@Nullable String cpuSetCpus,
String name,
Duration evalTimeout,
long sysoutLimit)
throws InterruptedException {
public String spawnContainer(long maxMemoryMegs, long cpus, @Nullable String cpuSetCpus,
String name, Duration evalTimeout, long sysoutLimit) throws InterruptedException {
String imageName = "togetherjava.org:5001/togetherjava/jshellwrapper";
boolean presentLocally =
client.listImagesCmd().withFilter("reference", List.of(imageName)).exec().stream()
.flatMap(it -> Arrays.stream(it.getRepoTags()))
.anyMatch(it -> it.endsWith(":master"));
boolean presentLocally = client.listImagesCmd()
.withFilter("reference", List.of(imageName))
.exec()
.stream()
.flatMap(it -> Arrays.stream(it.getRepoTags()))
.anyMatch(it -> it.endsWith(":master"));

if (!presentLocally) {
client.pullImageCmd(imageName)
.withTag("master")
.exec(new PullImageResultCallback())
.awaitCompletion(5, TimeUnit.MINUTES);
.withTag("master")
.exec(new PullImageResultCallback())
.awaitCompletion(5, TimeUnit.MINUTES);
}

return client.createContainerCmd(imageName + ":master")
.withHostConfig(
HostConfig.newHostConfig()
.withAutoRemove(true)
.withInit(true)
.withCapDrop(Capability.ALL)
.withNetworkMode("none")
.withPidsLimit(2000L)
.withReadonlyRootfs(true)
.withMemory(maxMemoryMegs * 1024 * 1024)
.withCpuCount(cpus)
.withCpusetCpus(cpuSetCpus))
.withStdinOpen(true)
.withAttachStdin(true)
.withAttachStderr(true)
.withAttachStdout(true)
.withEnv(
"evalTimeoutSeconds=" + evalTimeout.toSeconds(),
"sysOutCharLimit=" + sysoutLimit)
.withLabels(Map.of(WORKER_LABEL, WORKER_UNIQUE_ID.toString()))
.withName(name)
.exec()
.getId();
.withHostConfig(HostConfig.newHostConfig()
.withAutoRemove(true)
.withInit(true)
.withCapDrop(Capability.ALL)
.withNetworkMode("none")
.withPidsLimit(2000L)
.withReadonlyRootfs(true)
.withMemory(maxMemoryMegs * 1024 * 1024)
.withCpuCount(cpus)
.withCpusetCpus(cpuSetCpus))
.withStdinOpen(true)
.withAttachStdin(true)
.withAttachStderr(true)
.withAttachStdout(true)
.withEnv("evalTimeoutSeconds=" + evalTimeout.toSeconds(),
"sysOutCharLimit=" + sysoutLimit)
.withLabels(Map.of(WORKER_LABEL, WORKER_UNIQUE_ID.toString()))
.withName(name)
.exec()
.getId();
}

public InputStream startAndAttachToContainer(String containerId, InputStream stdin)
Expand All @@ -109,31 +103,28 @@ public InputStream startAndAttachToContainer(String containerId, InputStream std
PipedOutputStream pipeOut = new PipedOutputStream(pipeIn);

client.attachContainerCmd(containerId)
.withLogs(true)
.withFollowStream(true)
.withStdOut(true)
.withStdErr(true)
.withStdIn(stdin)
.exec(
new ResultCallback.Adapter<>() {
@Override
public void onNext(Frame object) {
try {
String payloadString =
new String(object.getPayload(), StandardCharsets.UTF_8);
if (object.getStreamType() == StreamType.STDOUT) {
pipeOut.write(object.getPayload());
} else {
LOGGER.warn(
"Received STDERR from container {}: {}",
containerId,
payloadString);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
});
.withLogs(true)
.withFollowStream(true)
.withStdOut(true)
.withStdErr(true)
.withStdIn(stdin)
.exec(new ResultCallback.Adapter<>() {
@Override
public void onNext(Frame object) {
try {
String payloadString =
new String(object.getPayload(), StandardCharsets.UTF_8);
if (object.getStreamType() == StreamType.STDOUT) {
pipeOut.write(object.getPayload());
} else {
LOGGER.warn("Received STDERR from container {}: {}", containerId,
payloadString);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
});

client.startContainerCmd(containerId).exec();
return pipeIn;
Expand Down
Loading

0 comments on commit 584f0f9

Please sign in to comment.