tdfs4ds.agentops.session_keeper¶
tdfs4ds.agentops.session_keeper
¶
Keep a deployed agent's Teradata session usable through long idle periods.
An AgentOps pod holds ONE teradataml context for the life of the process (turns
are serialized by the agent's turn lock). Seen live on AI Studio (0.3.6.0): after
about two idle hours, the first request with a new caller token never answered.
The pod log stopped on "opening Teradata session for caller ...", i.e. inside the
switch: closing the old context (tdml.remove_context(), whose garbage
collector sends a DROP VIEW over the old connection) or opening the new one.
Every later request then waited behind it on the turn lock. The most likely
cause is an idle connection dropped silently by the network, on which the driver
waits for an answer that never comes. Not proven from inside the pod, which is
why every step here also reports where it is.
Three tools, all fail-open and never raising:
- :func:
keepalive_loop- a lightSELECT 1everyintervalseconds under the agent's turn lock, so the connection is never idle long enough to be dropped. A ping that fails or times out reports the session dead. - :func:
close_context_bounded-remove_context()with a time limit. When it does not return, teradataml's connection globals are cleared so the nextcreate_context()does not try to close the dead connection again; the stuck call is left to finish (or not) in its daemon thread. - :func:
watchdog- writes every thread's stack to the pod log when a step takes longer than expected, so a hang names its own location.
_bounded
¶
Run fn in a daemon thread. Returns (finished, result_or_exception).
_abandon_context
¶
Forget the current teradataml connection without sending anything over it.
close_context_bounded
¶
Close the teradataml context, giving up after timeout seconds.
Returns 'none' (nothing open), 'closed', 'failed' (the close raised;
the context is cleared anyway) or 'abandoned' (it did not return in time:
the context is cleared and the stuck call is left in its daemon thread).
ping
¶
True when the current context answers SELECT 1 within timeout seconds.
keepalive_loop
async
¶
Ping the session every interval seconds while holding lock (the turn lock).
on_dead is called (inside the lock) when a ping fails, so the agent can close the dead session and open a new one on the next request. Runs until cancelled.
start_keepalive
¶
Start :func:keepalive_loop on the running event loop. Returns the task.
watchdog
¶
Dump every thread's stack to stderr (the pod log) if step exceeds seconds.