From b8d540e379a56d4ffc7009d6ff34b5d078f9f4f2 Mon Sep 17 00:00:00 2001 From: Alathreon Date: Tue, 21 May 2024 19:55:02 +0200 Subject: [PATCH] =?UTF-8?q?[Feature/SessionStats]=20Endpoint=20pour=20r?= =?UTF-8?q?=C3=A9cup=C3=A9rer=20les=20stats=20des=20sessions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/sessionstats/SessionStats.java | 17 +++++++++++++++++ .../jshellapi/rest/JShellController.java | 6 ++++++ .../jshellapi/service/JShellService.java | 18 ++++++++++++++++++ .../service/JShellSessionService.java | 8 ++++++++ 4 files changed, 49 insertions(+) create mode 100644 JShellAPI/src/main/java/org/togetherjava/jshellapi/dto/sessionstats/SessionStats.java diff --git a/JShellAPI/src/main/java/org/togetherjava/jshellapi/dto/sessionstats/SessionStats.java b/JShellAPI/src/main/java/org/togetherjava/jshellapi/dto/sessionstats/SessionStats.java new file mode 100644 index 0000000..270a05f --- /dev/null +++ b/JShellAPI/src/main/java/org/togetherjava/jshellapi/dto/sessionstats/SessionStats.java @@ -0,0 +1,17 @@ +package org.togetherjava.jshellapi.dto.sessionstats; + +/** + * Represents the stats of a session. + * + * @param id the id of this session + * @param timeSinceCreation the time in seconds since the creation of this session + * @param timeUntilExpiration the time in seconds until the expiration of this session + * @param totalEvalTime the time spent evaluating code + * @param doingOperation if the session is currently evaluating some code + */ +public record SessionStats( + String id, + long timeSinceCreation, + long timeUntilExpiration, + long totalEvalTime, + boolean doingOperation) {} diff --git a/JShellAPI/src/main/java/org/togetherjava/jshellapi/rest/JShellController.java b/JShellAPI/src/main/java/org/togetherjava/jshellapi/rest/JShellController.java index 63d2011..23bf309 100644 --- a/JShellAPI/src/main/java/org/togetherjava/jshellapi/rest/JShellController.java +++ b/JShellAPI/src/main/java/org/togetherjava/jshellapi/rest/JShellController.java @@ -6,6 +6,7 @@ import org.springframework.web.server.ResponseStatusException; import org.togetherjava.jshellapi.dto.JShellResult; import org.togetherjava.jshellapi.dto.JShellResultWithId; +import org.togetherjava.jshellapi.dto.sessionstats.SessionStats; import org.togetherjava.jshellapi.exceptions.DockerException; import org.togetherjava.jshellapi.service.JShellService; import org.togetherjava.jshellapi.service.JShellSessionService; @@ -89,6 +90,11 @@ public void delete(@PathVariable String id) throws DockerException { service.deleteSession(id); } + @GetMapping("sessions") + public List sessions() { + return service.fetchStats(); + } + @GetMapping("/startup_script/{id}") public String startupScript(@PathVariable StartupScriptId id) { return startupScriptsService.get(id); diff --git a/JShellAPI/src/main/java/org/togetherjava/jshellapi/service/JShellService.java b/JShellAPI/src/main/java/org/togetherjava/jshellapi/service/JShellService.java index e712f55..70eeb31 100644 --- a/JShellAPI/src/main/java/org/togetherjava/jshellapi/service/JShellService.java +++ b/JShellAPI/src/main/java/org/togetherjava/jshellapi/service/JShellService.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import org.springframework.lang.Nullable; import org.togetherjava.jshellapi.dto.*; +import org.togetherjava.jshellapi.dto.sessionstats.SessionStats; import org.togetherjava.jshellapi.exceptions.DockerException; import java.io.*; @@ -20,6 +21,8 @@ public class JShellService implements Closeable { private final String id; private final BufferedWriter writer; private final BufferedReader reader; + private final Instant creationTime; + private long totalEvalTime; private Instant lastTimeoutUpdate; private final long timeout; @@ -82,6 +85,7 @@ public JShellService( throw new DockerException("Creation of the session failed.", e); } this.doingOperation = false; + this.creationTime = Instant.now(); } public Optional eval(String code) throws DockerException { @@ -96,6 +100,7 @@ public Optional eval(String code) throws DockerException { } updateLastTimeout(); sessionService.scheduleEvalTimeoutValidation(id, evalTimeout + evalTimeoutValidationLeeway); + Instant start = Instant.now(); if (!code.endsWith("\n")) code += '\n'; try { writer.write("eval"); @@ -113,6 +118,7 @@ public Optional eval(String code) throws DockerException { close(); throw new DockerException(ex); } finally { + totalEvalTime += Duration.between(start, Instant.now()).getSeconds(); stopOperation(); } } @@ -231,6 +237,18 @@ public String id() { return id; } + public SessionStats fetchSessionInfo() { + long timeSinceCreation = Duration.between(creationTime, Instant.now()).getSeconds(); + long timeUntilExpiration = + Duration.between(Instant.now(), lastTimeoutUpdate.plusSeconds(timeout)) + .getSeconds(); + if (timeUntilExpiration < 0) { + timeUntilExpiration = 0; + } + return new SessionStats( + id, timeSinceCreation, timeUntilExpiration, totalEvalTime, doingOperation); + } + @Override public void close() { try { diff --git a/JShellAPI/src/main/java/org/togetherjava/jshellapi/service/JShellSessionService.java b/JShellAPI/src/main/java/org/togetherjava/jshellapi/service/JShellSessionService.java index 5aacbb8..20651e3 100644 --- a/JShellAPI/src/main/java/org/togetherjava/jshellapi/service/JShellSessionService.java +++ b/JShellAPI/src/main/java/org/togetherjava/jshellapi/service/JShellSessionService.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; import org.togetherjava.jshellapi.Config; +import org.togetherjava.jshellapi.dto.sessionstats.SessionStats; import org.togetherjava.jshellapi.exceptions.DockerException; import java.util.*; @@ -139,6 +140,13 @@ public void scheduleEvalTimeoutValidation(String id, long timeSeconds) { TimeUnit.SECONDS); } + public List fetchStats() { + return jshellSessions.values().stream() + .map(JShellService::fetchSessionInfo) + .sorted(Comparator.comparingLong(SessionStats::timeSinceCreation).reversed()) + .toList(); + } + @Autowired public void setConfig(Config config) { this.config = config;