Gateway Sessions¶
Web gateway instrument sessions and streaming poll loop
Instrument session layer: one worker thread per instrument.
All SCPI I/O for a session happens on its single worker thread (FIFO job queue), so compound operations are atomic and the non-thread-safe connection is never shared across threads (AUDIT.md C2). This module is FastAPI-free: the API layer adapts the returned concurrent.futures.Future to asyncio.
SessionError
¶
Bases: RuntimeError
Session is not in a state that can accept jobs (maps to HTTP 409).
InstrumentSession
¶
InstrumentSession(label: str, scope: Oscilloscope, mock: bool, address: Optional[str], poll_interval: float)
Source code in scpi_control/server/sessions.py
touch
¶
owner_watching
¶
True while at least one live stream opened by the current owner is connected.
Evaluated at check time against the current owner and the live per-identity watcher counts (see mark_owner_watching) -- never a snapshot taken when some stream connected. Ownership can change mid-stream via claim() or an explicit handoff, so "is the owner watching" must always be asked fresh: a snapshot fails open (a non-owner who claims the session while already watching would not be protected) and also sticks stale (a former owner's lingering socket would keep blocking claims after handoff).
A watching owner is never idle even though only writes touch() owner_last_active -- the claim rule refuses outright while this is true, regardless of the idle threshold.
Source code in scpi_control/server/sessions.py
mark_owner_watching
¶
Register that identity opened the live stream; returns an unmark callback.
Tracks the watching identity itself, not whether it happened to be
the owner at connect time -- owner_watching() does that comparison
later, at check time, against whoever owns the session then. The
returned callback decrements exactly once no matter how many times
it is called, so it is safe to invoke unconditionally from a
finally block on any disconnect path (clean close, error, or
cancellation).
Source code in scpi_control/server/sessions.py
SessionManager
¶
Registry of live sessions. create() connects before registering.