mirror of
https://github.com/sasjs/server.git
synced 2026-07-23 21:25:29 +00:00
f84af4ac06
The SAS-runtime poll loop in processProgram only checked for
SessionState.completed, so a session that failed (e.g. via %abort;)
left the loop spinning on delay(50) forever - the request never
resolved, even though the SAS log had already been written. Split a single completed-on-either-outcome
flag into separate completed/failed states without updating this loop.
- processProgram now throws when session.state becomes 'failed'
- Execution.ts catches that, reads the complete log (guaranteed
complete since the session's process has already exited by then),
and throws a SessionExecutionError carrying it
- stp.ts/code.ts surface { ..., log } in the HTTP error response
- add unit tests for the poll loop and the log-enrichment logic, plus
a mock SAS executable + end-to-end test exercising the real
session/process pipeline without needing a SAS install
- add docs/diagrams covering the session lifecycle and the SAS
execution handshake mechanism, for future context
39 lines
2.2 KiB
Markdown
39 lines
2.2 KiB
Markdown
# Code execution & session diagrams
|
|
|
|
Mermaid diagrams describing how `@sasjs/server` executes submitted code
|
|
(SAS/JS/PY/R) against pooled "sessions". Written for fast context-loading by
|
|
an AI coding agent: each diagram is self-contained, node/edge labels carry
|
|
the actual file:line references, and prose is kept to the minimum needed to
|
|
disambiguate the diagram.
|
|
|
|
| File | Covers |
|
|
|---|---|
|
|
| [session-lifecycle.md](session-lifecycle.md) | `SessionState` state machine; how it differs between the SAS runtime and the JS/PY/R runtimes |
|
|
| [sas-execution-handshake.md](sas-execution-handshake.md) | The SYSIN/AUTOEXEC file-swap mechanism a SAS session uses to turn one long-lived `sas` process into a single-use execution slot |
|
|
| [request-execution-flow.md](request-execution-flow.md) | End-to-end flowchart from HTTP request to response, covering session-pool acquisition and both runtime branches (SAS vs JS/PY/R) |
|
|
|
|
## Core concept
|
|
|
|
A "session" is not a request-scoped object. It is a pooled, reusable
|
|
execution slot with a filesystem folder (`session.path`) and a state
|
|
(`SessionState`). For the SAS runtime specifically, a session also owns one
|
|
real OS process, spawned at session-*creation* time and consumed by exactly
|
|
one code submission (see `sas-execution-handshake.md`). For JS/PY/R, a
|
|
session is just an ID + folder; the actual interpreter process is spawned
|
|
fresh per request inside `processProgram`.
|
|
|
|
## Key source files
|
|
|
|
- `api/src/controllers/internal/Session.ts` — session pool + lifecycle
|
|
(`SessionController`, `SASSessionController`), `SessionState` transitions.
|
|
- `api/src/controllers/internal/processProgram.ts` — writes the submitted
|
|
code into the session and drives it to completion/failure, per runtime.
|
|
- `api/src/controllers/internal/Execution.ts` — `ExecutionController`,
|
|
the entry point controllers call; acquires a session, calls
|
|
`processProgram`, reads back `log.log`/`webout.txt`/headers, builds the
|
|
HTTP response (or a `SessionExecutionError` on failure).
|
|
- `api/src/controllers/internal/create{SAS,JS,Python,R}Program.ts` —
|
|
per-runtime code templating (wraps the user's submitted code with
|
|
boilerplate: variable injection, `_webout` redirection, etc).
|
|
- `api/src/types/Session.ts` — `SessionState` enum and `Session` interface.
|