feat(kernel,server): rehydrate() + POST /sessions/{id}/resume
This commit is contained in:
@@ -188,6 +188,25 @@ class ServerModule(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rehydrates [artifactContentCache] from durable events and then resumes the session.
|
||||
* Called by [POST /sessions/{id}/resume] to restart a session after a server restart
|
||||
* without re-running already-completed stages.
|
||||
*/
|
||||
fun launchSessionResumeWithRehydrate(sessionId: SessionId, graph: com.correx.core.transitions.graph.WorkflowGraph) {
|
||||
activeSessionJobs.computeIfAbsent(sessionId) {
|
||||
moduleScope.launch {
|
||||
runCatching {
|
||||
orchestrator.rehydrate(sessionId)
|
||||
orchestrator.resume(sessionId, graph, defaultOrchestrationConfig)
|
||||
}.onFailure { e ->
|
||||
log.error("resumeSession (rehydrate): session={} failed", sessionId.value, e)
|
||||
}
|
||||
activeSessionJobs.remove(sessionId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resumeAbandonedSessions() {
|
||||
eventStore.allSessionIds().forEach { sessionId ->
|
||||
val orchState = orchestrationRepository.getState(sessionId)
|
||||
|
||||
@@ -43,6 +43,7 @@ fun Route.sessionRoutes(module: ServerModule) {
|
||||
getSessionRoute(module)
|
||||
cancelSessionRoute(module)
|
||||
undoSessionRoute(module)
|
||||
resumeSessionRoute(module)
|
||||
getEventsRoute(module)
|
||||
webSocket("/stream") {
|
||||
val id = call.parameters["id"] ?: return@webSocket
|
||||
@@ -98,6 +99,21 @@ private fun Route.undoSessionRoute(module: ServerModule) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun Route.resumeSessionRoute(module: ServerModule) {
|
||||
post("/resume") {
|
||||
val id = call.parameters["id"]
|
||||
?: return@post call.respond(HttpStatusCode.BadRequest, "Missing session id")
|
||||
val orchState = runCatching { module.orchestrationRepository.getState(TypeId(id)) }.getOrNull()
|
||||
?: return@post call.respond(HttpStatusCode.NotFound, "Session not found")
|
||||
val workflowId = orchState.workflowId.takeIf { it.isNotBlank() }
|
||||
?: return@post call.respond(HttpStatusCode.BadRequest, "Session has no workflowId")
|
||||
val graph = module.workflowRegistry.find(workflowId)
|
||||
?: return@post call.respond(HttpStatusCode.BadRequest, "Unknown workflowId: $workflowId")
|
||||
module.launchSessionResumeWithRehydrate(TypeId(id), graph)
|
||||
call.respond(HttpStatusCode.Accepted)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Route.getEventsRoute(module: ServerModule) {
|
||||
get("/events") {
|
||||
val id = call.parameters["id"]
|
||||
|
||||
Reference in New Issue
Block a user