serverpod-sessions
Serverpod Session의 생성·종료와 수명을 다룰 때 사용합니다. 공식 문서를 바탕으로 InternalSession과 정리 콜백을 확인하고 종료된 세션 오류를 조사합니다.
한마디로#
공식 문서를 바탕으로 InternalSession과 정리 콜백을 확인하고 종료된 세션 오류를 조사합니다.
무엇을·언제#
- 무엇을 해주나: 세션의 종류, 생성·종료(생명주기), 직접 만드는 InternalSession, 닫히기 직전 처리(cleanup) 방법을 정리해 줍니다.
-
언제 쓰나:
- 직접(수동으로) 세션을 만들어야 할 때
- "세션이 이미 닫혔다"는 오류를 만나 원인을 찾을 때
- 세션이 언제 만들어지고 언제 닫히는지 흐름을 이해하고 싶을 때
- 핵심 주의: 직접 만든 세션을 닫지 않으면 메모리가 새고 기록(로그)도 남지 않습니다. 그래서 "항상 닫기"가 중요합니다.
핵심 용어#
| 용어 | 쉬운 설명 |
|---|---|
| Session(세션) | 서버가 한 작업을 처리하는 동안 쓰는 도구 묶음(가방). 끝나면 반납(닫기)함 |
| InternalSession | 사람이 직접 만들고 직접 닫아야 하는 세션 |
| lifecycle(생명주기) | 세션이 생기고 살아 있다가 닫히는 전체 흐름 |
| cleanup callback | 세션이 닫히기 직전에 자동으로 실행되는 마무리 처리 |
| StateError | 이미 닫힌 세션을 다시 쓰려 할 때 나는 오류 |
| future call | 나중에(지연 후) 실행하도록 예약하는 작업. 닫힌 세션을 붙잡는 대신 사용 |
A Session provides access to database, cache, storage, messages, passwords, and logging. The framework creates and closes sessions automatically; only InternalSession requires manual management. Do not store a request session for work that outlives the request/stream/future call.
Session types#
| Type | Created for | Lifetime |
|---|---|---|
| MethodCallSession | Endpoint methods | Single request |
| WebCallSession | Web server routes | Single request |
| MethodStreamSession | Stream methods | Stream duration |
| StreamingSession | WebSocket connections | Connection duration |
| FutureCallSession | Future calls | Task execution |
| InternalSession | Manual creation | Until closed |
Manual sessions (InternalSession)#
Always close in a finally block:
var session = await Serverpod.instance.createSession();
try {
await doWork(session);
} finally {
await session.close();
}
Unclosed sessions leak memory and never persist logs. Using a closed session throws StateError.
Cleanup callbacks#
session.addWillCloseListener((session) async {
// Runs just before session closes (all session types)
});
Common pitfall: using session after method returns#
Sessions close when the endpoint returns. Do not capture for later use:
// BAD — session already closed when callback runs
Timer(Duration(seconds: 5), () => user.updateLastSeen(session));
Fix: Use a future call (session.serverpod.futureCalls.callWithDelay(...)) or create a new InternalSession inside the callback and close it in
finally.
Serverpod 4.0 (beta)#
Serverpod cut 4.0.0-beta.0 off the 3.5.0-beta.* line (previously referred to as "Serverpod 4 tech preview" — now versioned as beta, still not GA). Production services in this repo still target Serverpod 3.x, so everything above remains valid. New session-related changes across
3.5.0-beta.1–4.0.0-beta.0:
-
Serverpod.instance.withSession(...)helper (3.5.0-beta.11): wraps manualInternalSessioncreation with automatic teardown, so you no longer have to hand-write thetry/finallypattern above:await Serverpod.instance.withSession((session) async { await doWork(session); }); -
Not-configured features throw
StateError(3.5.0-beta.11): calling a session feature that isn't configured (e.g. cache/storage without the backing service set up) now consistently throwsStateErrorinstead of a genericException— the same exception type as the "already closed" case above.
Beta version pin: serverpod: 4.0.0-beta.0, Dart SDK ^3.10.3, Flutter ^3.38.4.