feat(server): add open session core #74

Merged
Lochnair merged 3 commits from feat/server-core-open into main 2026-08-11 18:12:42 +00:00
3 changed files with 27 additions and 8 deletions
Showing only changes of commit b7e206f939 - Show all commits

No files matched your search

+9 -2
View File
@@ -68,6 +68,10 @@ impl ServerCore {
} }
/// The number of live sessions. /// The number of live sessions.
///
/// This is the observable a caller genuinely needs — how much session state
/// the server is holding against its bound. The sessions themselves stay
/// crate-private until their shape settles.
#[must_use] #[must_use]
pub fn session_count(&self) -> usize { pub fn session_count(&self) -> usize {
self.sessions.len() self.sessions.len()
@@ -78,8 +82,11 @@ impl ServerCore {
/// This is a lookup by token alone and is therefore *not* an admission /// This is a lookup by token alone and is therefore *not* an admission
/// check: a request is bound to a session only when the token matches and /// check: a request is bound to a session only when the token matches and
/// it arrived from the session's exact endpoint. /// it arrived from the session's exact endpoint.
#[must_use] //
pub fn session(&self, token: u64) -> Option<&Session> { // Called only by tests until echo and close processing arrive, which is
// what a token lookup is for.
#[allow(dead_code)]
pub(crate) fn session(&self, token: u64) -> Option<&Session> {
self.sessions.get(&token) self.sessions.get(&token)
} }
-1
View File
@@ -50,4 +50,3 @@ mod tests;
pub use config::{ServerConfig, DEFAULT_MAX_SESSIONS}; pub use config::{ServerConfig, DEFAULT_MAX_SESSIONS};
pub use core::ServerCore; pub use core::ServerCore;
pub use error::ServerError; pub use error::ServerError;
pub use session::Session;
+18 -5
View File
@@ -9,8 +9,13 @@ use irtt_proto::Params;
/// state (activity, deadlines, expiry) belong to the slices that implement /// state (activity, deadlines, expiry) belong to the slices that implement
/// those behaviors, and are deliberately absent rather than present as /// those behaviors, and are deliberately absent rather than present as
/// placeholders. /// placeholders.
///
/// Deliberately crate-private. The next slices are all but certain to add and
/// restructure fields here, and nothing outside the crate needs a session yet;
/// publishing internal session state before ECHO even exists would buy nothing
/// and commit us to a shape we are about to change.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct Session { pub(crate) struct Session {
peer: SocketAddr, peer: SocketAddr,
params: Params, params: Params,
} }
@@ -27,15 +32,23 @@ impl Session {
/// all form part of its identity. Echo and close processing, once /// all form part of its identity. Echo and close processing, once
/// implemented, must require both a token match and an exact endpoint match /// implemented, must require both a token match and an exact endpoint match
/// before touching a session. /// before touching a session.
#[must_use] //
pub fn peer(&self) -> SocketAddr { // Read only by tests until then. The endpoint has to be captured at open
// time — it is not recoverable later — so this slice stores state whose
// production consumer is the next one, and the tests prove it is stored
// exactly.
#[allow(dead_code)]
pub(crate) fn peer(&self) -> SocketAddr {
self.peer self.peer
} }
/// The negotiated parameters the server returned for this session and will /// The negotiated parameters the server returned for this session and will
/// enforce for it. /// enforce for it.
#[must_use] //
pub fn params(&self) -> &Params { // Also awaiting its production consumer: echo replies are built from the
// negotiated params.
#[allow(dead_code)]
pub(crate) fn params(&self) -> &Params {
&self.params &self.params
} }
} }