Skip to content

Commit b0b959a

Browse files
committed
[Feature/SessionStats] Endpoint to fetch session data
1 parent daddfe9 commit b0b959a

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.togetherjava.jshellapi.dto.sessionstats;
2+
3+
/**
4+
* Represents the stats of a session.
5+
*
6+
* @param id the id of this session
7+
* @param timeSinceCreation the time in seconds since the creation of this session
8+
* @param timeUntilExpiration the time in seconds until the expiration of this session
9+
* @param totalEvalTime the time spent evaluating code
10+
* @param doingOperation if the session is currently evaluating some code
11+
*/
12+
public record SessionStats(
13+
String id,
14+
long timeSinceCreation,
15+
long timeUntilExpiration,
16+
long totalEvalTime,
17+
boolean doingOperation) {}

JShellAPI/src/main/java/org/togetherjava/jshellapi/rest/JShellController.java

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import org.togetherjava.jshellapi.dto.JShellResult;
99
import org.togetherjava.jshellapi.dto.JShellResultWithId;
10+
import org.togetherjava.jshellapi.dto.sessionstats.SessionStats;
1011
import org.togetherjava.jshellapi.exceptions.DockerException;
1112
import org.togetherjava.jshellapi.service.JShellService;
1213
import org.togetherjava.jshellapi.service.JShellSessionService;
@@ -71,6 +72,11 @@ public void delete(@PathVariable String id) throws DockerException {
7172
service.deleteSession(id);
7273
}
7374

75+
@GetMapping("sessions")
76+
public List<SessionStats> sessions() {
77+
return service.fetchStats();
78+
}
79+
7480
@GetMapping("/startup_script/{id}")
7581
public String startupScript(@PathVariable StartupScriptId id) {
7682
return startupScriptsService.get(id);

JShellAPI/src/main/java/org/togetherjava/jshellapi/service/JShellService.java

+18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.springframework.lang.Nullable;
77

88
import org.togetherjava.jshellapi.dto.*;
9+
import org.togetherjava.jshellapi.dto.sessionstats.SessionStats;
910
import org.togetherjava.jshellapi.exceptions.DockerException;
1011

1112
import java.io.*;
@@ -21,6 +22,8 @@ public class JShellService implements Closeable {
2122
private final String id;
2223
private final BufferedWriter writer;
2324
private final BufferedReader reader;
25+
private final Instant creationTime;
26+
private long totalEvalTime;
2427

2528
private Instant lastTimeoutUpdate;
2629
private final long timeout;
@@ -66,6 +69,7 @@ public JShellService(DockerService dockerService, JShellSessionService sessionSe
6669
throw new DockerException("Creation of the session failed.", e);
6770
}
6871
this.doingOperation = false;
72+
this.creationTime = Instant.now();
6973
}
7074

7175
public Optional<JShellResult> eval(String code) throws DockerException {
@@ -80,6 +84,7 @@ public Optional<JShellResult> eval(String code) throws DockerException {
8084
}
8185
updateLastTimeout();
8286
sessionService.scheduleEvalTimeoutValidation(id, evalTimeout + evalTimeoutValidationLeeway);
87+
Instant start = Instant.now();
8388
if (!code.endsWith("\n"))
8489
code += '\n';
8590
try {
@@ -98,6 +103,7 @@ public Optional<JShellResult> eval(String code) throws DockerException {
98103
close();
99104
throw new DockerException(ex);
100105
} finally {
106+
totalEvalTime += Duration.between(start, Instant.now()).getSeconds();
101107
stopOperation();
102108
}
103109
}
@@ -204,6 +210,18 @@ public String id() {
204210
return id;
205211
}
206212

213+
public SessionStats fetchSessionInfo() {
214+
long timeSinceCreation = Duration.between(creationTime, Instant.now()).getSeconds();
215+
long timeUntilExpiration =
216+
Duration.between(Instant.now(), lastTimeoutUpdate.plusSeconds(timeout))
217+
.getSeconds();
218+
if (timeUntilExpiration < 0) {
219+
timeUntilExpiration = 0;
220+
}
221+
return new SessionStats(
222+
id, timeSinceCreation, timeUntilExpiration, totalEvalTime, doingOperation);
223+
}
224+
207225
@Override
208226
public void close() {
209227
LOGGER.debug("Close called for session {}.", id);

JShellAPI/src/main/java/org/togetherjava/jshellapi/service/JShellSessionService.java

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.springframework.web.server.ResponseStatusException;
1010

1111
import org.togetherjava.jshellapi.Config;
12+
import org.togetherjava.jshellapi.dto.sessionstats.SessionStats;
1213
import org.togetherjava.jshellapi.exceptions.DockerException;
1314

1415
import java.util.*;
@@ -133,6 +134,13 @@ public void scheduleEvalTimeoutValidation(String id, long timeSeconds) {
133134
}, timeSeconds, TimeUnit.SECONDS);
134135
}
135136

137+
public List<SessionStats> fetchStats() {
138+
return jshellSessions.values().stream()
139+
.map(JShellService::fetchSessionInfo)
140+
.sorted(Comparator.comparingLong(SessionStats::timeSinceCreation).reversed())
141+
.toList();
142+
}
143+
136144
@Autowired
137145
public void setConfig(Config config) {
138146
this.config = config;

0 commit comments

Comments
 (0)