pub struct AppState {
pub llm_activity: LlmActivityTracker,
/* private fields */
}Expand description
Global application state
Fields§
§llm_activity: LlmActivityTrackerImplementations§
Source§impl AppState
impl AppState
Sourcepub fn new_with_options(
include_disabled_protocols: bool,
ollama_url: String,
) -> Self
pub fn new_with_options( include_disabled_protocols: bool, ollama_url: String, ) -> Self
Create a new application state with options
Sourcepub async fn add_server(&self, server: ServerInstance) -> ServerId
pub async fn add_server(&self, server: ServerInstance) -> ServerId
Add a new server instance and return its ID
Sourcepub async fn remove_server(&self, id: ServerId) -> Option<ServerInstance>
pub async fn remove_server(&self, id: ServerId) -> Option<ServerInstance>
Remove a server instance, aborting its background tasks and cancelling the scheduled tasks scoped to it.
The cleanup is done here rather than left to callers: MCP’s stop_server and
stop_all did the removal without it, so every server- and connection-scoped
scheduled task survived its server and kept firing on its interval.
Sourcepub async fn add_pipe(
&self,
from: ServerId,
on: String,
to: ServerId,
as_action: String,
map: BTreeMap<String, String>,
) -> Result<PipeId>
pub async fn add_pipe( &self, from: ServerId, on: String, to: ServerId, as_action: String, map: BTreeMap<String, String>, ) -> Result<PipeId>
Declare a pipe: forward from’s on events into to as as_action,
rendering map templates against the event data.
Fails cleanly if either endpoint does not exist, or if the edge would
close a cycle among existing pipes (including the self-loop from == to).
Sourcepub async fn remove_pipe(&self, id: PipeId) -> Option<PipeSpec>
pub async fn remove_pipe(&self, id: PipeId) -> Option<PipeSpec>
Remove a pipe by id, returning it if present.
Sourcepub async fn list_pipes(&self) -> Vec<PipeSpec>
pub async fn list_pipes(&self) -> Vec<PipeSpec>
All declared pipes (cloned).
Sourcepub async fn pipes_matching(
&self,
from: ServerId,
event_id: &str,
) -> Vec<PipeSpec>
pub async fn pipes_matching( &self, from: ServerId, event_id: &str, ) -> Vec<PipeSpec>
Pipes whose source is from and that tap event_id.
Sourcepub fn register_server_task(
&self,
id: ServerId,
handle: JoinHandle<()>,
) -> impl Future<Output = ()> + Send + '_
pub fn register_server_task( &self, id: ServerId, handle: JoinHandle<()>, ) -> impl Future<Output = ()> + Send + '_
Register a background task owned by a server so it can be aborted on stop.
Protocol spawn implementations call this with the JoinHandle of every
long-lived task they spawn — accept loop, datagram reader, interface reader —
right after spawning it. Handles ACCUMULATE: registering a second task no
longer discards the first, so a protocol with two loops gets both aborted.
Finished handles are pruned on each registration so a protocol that registers a task per connection cannot grow the vector without bound.
If the server was already removed (raced with stop), the task is aborted immediately to avoid leaking the listener. Cancellation, including dropping the returned future before its first poll, aborts the child until ownership has transferred into the registry.
Sourcepub async fn spawn_server_task<F>(&self, id: ServerId, future: F) -> AbortHandle
pub async fn spawn_server_task<F>(&self, id: ServerId, future: F) -> AbortHandle
Spawn a task the server owns and register it, in one call.
Prefer this over tokio::spawn + register_server_task for per-connection tasks.
A measurement on 15 September 2026 found 301 tokio::spawn calls across
src/server/*/mod.rs against 159 register_server_task calls, in 102 protocols — and
the unregistered ones are almost entirely the per-connection tasks, because the accept
loop is the handle a protocol remembers to register and the connection it just accepted
is the one it forgets. The consequence is the one the root CLAUDE.md records:
stop_server releases the listening socket and in-flight connections keep running,
still answering, still costing LLM budget, on a server the operator has stopped.
Two properties make this safe to call per connection, both inherited from
Self::register_server_task: finished handles are pruned on every registration, so
the vector cannot grow without bound however many connections arrive; and a task
spawned against an already-removed server is aborted immediately rather than leaking
past its owner, which closes the accept-then-stop race.
Returns an tokio::task::AbortHandle for the rare caller that needs to cancel the
task itself before the server stops; most callers discard it.
Sourcepub async fn spawn_client_task<F>(&self, id: ClientId, future: F) -> AbortHandle
pub async fn spawn_client_task<F>(&self, id: ClientId, future: F) -> AbortHandle
The client-side twin of Self::spawn_server_task. Same reasoning: a client that
spawns a task per request should not have to remember two calls.
Sourcepub async fn register_server_handle<T: Any + Send + Sync>(
&self,
id: ServerId,
handle: Arc<T>,
)
pub async fn register_server_handle<T: Any + Send + Sync>( &self, id: ServerId, handle: Arc<T>, )
Register a handle to the running instance of a server, so protocol actions can reach its live state.
A protocol’s spawn() calls this with whatever type carries its live state —
typically a struct of mpsc::Senders and shared views. The type is erased
here so AppState never learns any protocol’s types; the protocol recovers
it with Self::server_handle.
Registering against an already-removed server is a no-op: the handle is dropped rather than resurrecting an entry for a server that is gone.
§Reaching this from an action
Async actions are dispatched through Server::execute_action() on the
stateless protocol struct, which is why they can only return NoAction
today. Making this registry reachable needs one change in
src/llm/actions/, both parts mechanical:
// src/llm/actions/protocol_trait.rs, in `trait Server`:
fn execute_action_with_state(
&self,
action: serde_json::Value,
state: AppState, // cheap: AppState is an Arc
server_id: Option<crate::state::ServerId>,
) -> std::pin::Pin<
Box<dyn std::future::Future<Output = anyhow::Result<ActionResult>> + Send + '_>,
> {
// Default keeps every existing protocol working untouched.
let _ = (state, server_id);
let result = self.execute_action(action);
Box::pin(async move { result })
}
// src/llm/actions/executor.rs, replacing the `proto.execute_action(...)` call:
match proto
.execute_action_with_state(action.clone(), state.clone(), server_id)
.await
{ /* unchanged */ }A protocol that needs live state then overrides execute_action_with_state,
calls state.server_handle::<MyHandle>(server_id?), and talks to its own
running server. Nothing about the stateless path changes.
Sourcepub async fn server_handle<T: Any + Send + Sync>(
&self,
id: ServerId,
) -> Option<Arc<T>>
pub async fn server_handle<T: Any + Send + Sync>( &self, id: ServerId, ) -> Option<Arc<T>>
Look up the live-instance handle of a server, downcast to the protocol’s own handle type.
Returns None if the server is gone, never registered a handle, or
registered one of a different type — a protocol asking for someone else’s
handle gets a miss, not a panic.
Sourcepub async fn has_server_handle(&self, id: ServerId) -> bool
pub async fn has_server_handle(&self, id: ServerId) -> bool
Whether a server has registered a live-instance handle
Sourcepub async fn park_intercept(
&self,
owner: InterceptOwner,
connection_id: Option<u32>,
event_type: &str,
description: &str,
event_data: Option<Value>,
timeout_secs: u64,
) -> (u64, Receiver<Vec<Value>>)
pub async fn park_intercept( &self, owner: InterceptOwner, connection_id: Option<u32>, event_type: &str, description: &str, event_data: Option<Value>, timeout_secs: u64, ) -> (u64, Receiver<Vec<Value>>)
Park an event for a human to answer. Returns the intercept id and the receiver the dispatcher must await (under its own timeout).
Sourcepub async fn list_intercepts(&self) -> Vec<InterceptView>
pub async fn list_intercepts(&self) -> Vec<InterceptView>
Pending intercepts, oldest first, with dead entries pruned.
Sourcepub async fn resolve_intercept(
&self,
id: u64,
actions: Vec<Value>,
) -> Result<(), String>
pub async fn resolve_intercept( &self, id: u64, actions: Vec<Value>, ) -> Result<(), String>
Answer a parked event with the operator’s actions.
Errors if the intercept is gone — already answered, dismissed, or the waiting dispatcher gave up (timeout / connection closed). The answer is then NOT delivered anywhere; the peer has already received the fail-closed reply.
Sourcepub async fn dismiss_intercept(&self, id: u64) -> bool
pub async fn dismiss_intercept(&self, id: u64) -> bool
Refuse a parked event: the dispatcher sees “no answer” immediately and takes the fail-closed path instead of waiting out its timeout.
Sourcepub async fn remove_intercept(&self, id: u64)
pub async fn remove_intercept(&self, id: u64)
Drop a parked entry without answering (the dispatcher cleans up after its own timeout so the list never shows a question nobody is waiting on).
Sourcepub async fn register_peer_handle(
&self,
server_id: ServerId,
connection_id: u32,
handle: ClientHandle,
)
pub async fn register_peer_handle( &self, server_id: ServerId, connection_id: u32, handle: ClientHandle, )
Register a command channel into one connection of a server. Only protocols that adopted peer messaging call this; the dashboard offers “message this peer” exactly where a handle exists.
Sourcepub async fn has_peer_handle(
&self,
server_id: ServerId,
connection_id: u32,
) -> bool
pub async fn has_peer_handle( &self, server_id: ServerId, connection_id: u32, ) -> bool
Whether a connection accepts injected actions.
Sourcepub async fn remove_peer_handle(&self, server_id: ServerId, connection_id: u32)
pub async fn remove_peer_handle(&self, server_id: ServerId, connection_id: u32)
Drop a connection’s command handle (the owning loop does this when the connection closes).
Sourcepub fn register_peer_task(
&self,
server_id: ServerId,
connection_id: u32,
handle: JoinHandle<()>,
) -> impl Future<Output = ()> + Send + '_
pub fn register_peer_task( &self, server_id: ServerId, connection_id: u32, handle: JoinHandle<()>, ) -> impl Future<Output = ()> + Send + '_
Track a peer worker under its connection. A close racing registration aborts it immediately; registration never revives a removed handle.
Sourcepub async fn send_to_peer(
&self,
server_id: ServerId,
connection_id: u32,
action: Value,
timeout: Duration,
) -> Result<ClientSendOutcome>
pub async fn send_to_peer( &self, server_id: ServerId, connection_id: u32, action: Value, timeout: Duration, ) -> Result<ClientSendOutcome>
Execute one action inside a server connection’s own task and wait for
the outcome. Same lock discipline as send_to_client: clone the handle
out, drop the guard, then await.
Sourcepub async fn register_client_handle(&self, id: ClientId, handle: ClientHandle)
pub async fn register_client_handle(&self, id: ClientId, handle: ClientHandle)
Register the command channel for a running client. No-op if the client
row is already gone (raced with stop_client) — the caller’s receiver
is then the only reference and sends fail cleanly.
Sourcepub async fn client_handle(&self, id: ClientId) -> Option<ClientHandle>
pub async fn client_handle(&self, id: ClientId) -> Option<ClientHandle>
The command handle for a client, if its loop registered one.
Sourcepub async fn has_client_handle(&self, id: ClientId) -> bool
pub async fn has_client_handle(&self, id: ClientId) -> bool
Whether a running client accepts injected commands. The UI uses this to grey out [send] for clients that have not adopted the channel.
Sourcepub async fn remove_client_handle(&self, id: ClientId)
pub async fn remove_client_handle(&self, id: ClientId)
Drop a client’s command handle (called by the loop on exit; also done
by remove_client).
Sourcepub async fn send_to_client(
&self,
id: ClientId,
action: Value,
timeout: Duration,
) -> Result<ClientSendOutcome>
pub async fn send_to_client( &self, id: ClientId, action: Value, timeout: Duration, ) -> Result<ClientSendOutcome>
Execute one action inside a running client’s connection loop and wait for the outcome.
Lock discipline: the handle is cloned out under the read guard and the guard dropped before any await on the channel.
Sourcepub async fn server_task_count(&self, id: ServerId) -> usize
pub async fn server_task_count(&self, id: ServerId) -> usize
Number of background tasks currently tracked for a server
Sourcepub async fn get_server(&self, id: ServerId) -> Option<ServerInstance>
pub async fn get_server(&self, id: ServerId) -> Option<ServerInstance>
Get a server instance (cloned)
Sourcepub async fn get_all_server_ids(&self) -> Vec<ServerId>
pub async fn get_all_server_ids(&self) -> Vec<ServerId>
Get all server IDs
Sourcepub async fn get_all_servers(&self) -> Vec<ServerInstance>
pub async fn get_all_servers(&self) -> Vec<ServerInstance>
Get all servers (cloned)
Sourcepub async fn update_server_status(&self, id: ServerId, status: ServerStatus)
pub async fn update_server_status(&self, id: ServerId, status: ServerStatus)
Update server status
Sourcepub async fn update_server_local_addr(
&self,
id: ServerId,
local_addr: SocketAddr,
)
pub async fn update_server_local_addr( &self, id: ServerId, local_addr: SocketAddr, )
Update server local listening address
Sourcepub async fn get_instruction(&self, server_id: ServerId) -> Option<String>
pub async fn get_instruction(&self, server_id: ServerId) -> Option<String>
Get instruction for a specific server
Sourcepub async fn set_instruction(&self, server_id: ServerId, instruction: String)
pub async fn set_instruction(&self, server_id: ServerId, instruction: String)
Set instruction for a specific server
Sourcepub async fn get_memory(&self, server_id: ServerId) -> Option<String>
pub async fn get_memory(&self, server_id: ServerId) -> Option<String>
Get memory for a specific server
Sourcepub async fn set_memory(&self, server_id: ServerId, memory: String)
pub async fn set_memory(&self, server_id: ServerId, memory: String)
Set memory for a specific server
Sourcepub async fn append_memory(&self, server_id: ServerId, text: String)
pub async fn append_memory(&self, server_id: ServerId, text: String)
Append to memory for a specific server
Sourcepub async fn add_server_feedback(
&self,
server_id: ServerId,
feedback: Value,
) -> Result<()>
pub async fn add_server_feedback( &self, server_id: ServerId, feedback: Value, ) -> Result<()>
Add feedback to a server’s feedback buffer
Feedback is accumulated and processed later via debounced LLM invocation Returns Ok if feedback was added, Err if server not found or feedback_instructions not set
Sourcepub async fn take_due_feedback(&self, debounce: Duration) -> Vec<DueFeedback>
pub async fn take_due_feedback(&self, debounce: Duration) -> Vec<DueFeedback>
Take the feedback that is due for processing, emptying those buffers.
Leading-edge debounce: an instance is due as soon as it has any buffered feedback
and debounce has elapsed since its last processing (so the first feedback after a
quiet period is acted on at the next tick, and a burst is coalesced into one call).
last_feedback_processed is stamped here rather than after the LLM answers, so a
slow or failing call cannot re-trigger itself on every tick.
Draining here — under the same write lock that stamps the timestamp — is what makes the caller safe to run from a 1s timer: two ticks can never take the same entries.
Sourcepub async fn add_client_feedback(
&self,
client_id: ClientId,
feedback: Value,
) -> Result<()>
pub async fn add_client_feedback( &self, client_id: ClientId, feedback: Value, ) -> Result<()>
Add feedback to a client’s feedback buffer
Feedback is accumulated and processed later via debounced LLM invocation Returns Ok if feedback was added, Err if client not found or feedback_instructions not set
Sourcepub fn get_first_server_id_sync(&self) -> Option<ServerId>
pub fn get_first_server_id_sync(&self) -> Option<ServerId>
Get first server ID (synchronous version for use in non-async contexts)
This is a non-blocking helper that attempts to get the first server ID Returns None if unable to acquire lock or no servers exist
Sourcepub async fn get_ollama_model(&self) -> Option<String>
pub async fn get_ollama_model(&self) -> Option<String>
Get the Ollama model name
Sourcepub async fn set_ollama_model(&self, model: Option<String>)
pub async fn set_ollama_model(&self, model: Option<String>)
Set the Ollama model name
Sourcepub async fn get_scripting_env(&self) -> ScriptingEnvironment
pub async fn get_scripting_env(&self) -> ScriptingEnvironment
Get the scripting environment information
Sourcepub async fn set_scripting_env(&self, env: ScriptingEnvironment)
pub async fn set_scripting_env(&self, env: ScriptingEnvironment)
Set scripting environment
This is primarily used for testing to inject a mock environment. In production, the environment is auto-detected at startup.
Sourcepub async fn get_selected_scripting_mode(&self) -> ScriptingMode
pub async fn get_selected_scripting_mode(&self) -> ScriptingMode
Get the currently selected scripting mode
Sourcepub async fn set_selected_scripting_mode(&self, mode: ScriptingMode)
pub async fn set_selected_scripting_mode(&self, mode: ScriptingMode)
Set the selected scripting mode
Sourcepub async fn cycle_scripting_mode(&self) -> (ScriptingMode, bool)
pub async fn cycle_scripting_mode(&self) -> (ScriptingMode, bool)
Cycle between ON and OFF scripting modes Returns the new mode and whether any switch occurred
Sourcepub async fn is_server_docs_read(&self) -> bool
pub async fn is_server_docs_read(&self) -> bool
Check if server documentation has been read (enables open_server)
Sourcepub async fn is_client_docs_read(&self) -> bool
pub async fn is_client_docs_read(&self) -> bool
Check if client documentation has been read (enables open_client)
Sourcepub async fn mark_server_protocols_documented(&self, protocols: &[String])
pub async fn mark_server_protocols_documented(&self, protocols: &[String])
Mark server protocols as documented
Sourcepub async fn mark_client_protocols_documented(&self, protocols: &[String])
pub async fn mark_client_protocols_documented(&self, protocols: &[String])
Mark client protocols as documented
Sourcepub async fn get_documented_server_protocols(&self) -> HashSet<String>
pub async fn get_documented_server_protocols(&self) -> HashSet<String>
Get all documented server protocols
Sourcepub async fn get_documented_client_protocols(&self) -> HashSet<String>
pub async fn get_documented_client_protocols(&self) -> HashSet<String>
Get all documented client protocols
Sourcepub async fn get_event_handler_mode(&self) -> EventHandlerMode
pub async fn get_event_handler_mode(&self) -> EventHandlerMode
Get the currently selected event handler mode
Sourcepub async fn set_event_handler_mode(&self, mode: EventHandlerMode)
pub async fn set_event_handler_mode(&self, mode: EventHandlerMode)
Set the event handler mode
Sourcepub async fn cycle_event_handler_mode(&self) -> EventHandlerMode
pub async fn cycle_event_handler_mode(&self) -> EventHandlerMode
Cycle event handler mode through ANY -> SCRIPT -> STATIC -> LLM -> ANY Returns the new mode
Sourcepub async fn get_web_search_mode(&self) -> WebSearchMode
pub async fn get_web_search_mode(&self) -> WebSearchMode
Get the current web search mode
Sourcepub async fn set_web_search_mode(&self, mode: WebSearchMode)
pub async fn set_web_search_mode(&self, mode: WebSearchMode)
Set the web search mode
Sourcepub async fn cycle_web_search_mode(&self) -> WebSearchMode
pub async fn cycle_web_search_mode(&self) -> WebSearchMode
Cycle web search mode through ON -> ASK -> OFF -> ON and return the new state
Sourcepub async fn set_web_approval_channel(
&self,
tx: UnboundedSender<WebApprovalRequest>,
)
pub async fn set_web_approval_channel( &self, tx: UnboundedSender<WebApprovalRequest>, )
Set the web approval channel (called by TUI on startup)
Sourcepub async fn get_web_approval_channel(
&self,
) -> Option<UnboundedSender<WebApprovalRequest>>
pub async fn get_web_approval_channel( &self, ) -> Option<UnboundedSender<WebApprovalRequest>>
Get a clone of the web approval channel
Sourcepub async fn get_include_disabled_protocols(&self) -> bool
pub async fn get_include_disabled_protocols(&self) -> bool
Get whether disabled protocols should be included
Sourcepub async fn get_min_stability(&self) -> Option<DevelopmentState>
pub async fn get_min_stability(&self) -> Option<DevelopmentState>
Get the minimum stability required to start a protocol, if any
(None = no gate).
Sourcepub async fn set_min_stability(&self, min: Option<DevelopmentState>)
pub async fn set_min_stability(&self, min: Option<DevelopmentState>)
Set the minimum stability required to start a protocol (from
--min-stability). None disables the gate.
Sourcepub async fn get_ollama_url(&self) -> String
pub async fn get_ollama_url(&self) -> String
Get the Ollama API base URL
Sourcepub async fn set_llm_client(&self, client: OllamaClient)
pub async fn set_llm_client(&self, client: OllamaClient)
Set the configured LLM client
Sourcepub async fn get_llm_client(&self) -> Option<OllamaClient>
pub async fn get_llm_client(&self) -> Option<OllamaClient>
Get the configured LLM client
Sourcepub async fn get_rate_limiter(&self) -> RateLimiter
pub async fn get_rate_limiter(&self) -> RateLimiter
Get the rate limiter
Sourcepub async fn configure_rate_limiter(
&self,
config: RateLimiterConfig,
) -> Result<()>
pub async fn configure_rate_limiter( &self, config: RateLimiterConfig, ) -> Result<()>
Configure the rate limiter
Sourcepub async fn get_instance_id(&self) -> String
pub async fn get_instance_id(&self) -> String
Get the unique instance ID for this NetGet process
Sourcepub async fn get_system_capabilities(&self) -> SystemCapabilities
pub async fn get_system_capabilities(&self) -> SystemCapabilities
Get system capabilities detected at startup
Sourcepub async fn get_next_unified_id(&self) -> u32
pub async fn get_next_unified_id(&self) -> u32
Get the next unified ID (for connections) This ensures all IDs (servers, connections, clients) are unique across all types
Sourcepub async fn set_event_handler_config(
&self,
server_id: ServerId,
config: Option<EventHandlerConfig>,
)
pub async fn set_event_handler_config( &self, server_id: ServerId, config: Option<EventHandlerConfig>, )
Update event handler configuration for a server
Sourcepub async fn get_event_handler_config(
&self,
server_id: ServerId,
) -> Option<EventHandlerConfig>
pub async fn get_event_handler_config( &self, server_id: ServerId, ) -> Option<EventHandlerConfig>
Get event handler configuration for a server
Sourcepub async fn get_summary(&self) -> String
pub async fn get_summary(&self) -> String
Get a summary of current state for LLM context
Sourcepub async fn get_protocol_name(&self, server_id: ServerId) -> Option<String>
pub async fn get_protocol_name(&self, server_id: ServerId) -> Option<String>
Get protocol name for a server
Sourcepub async fn cleanup_old_connections(&self, max_age_secs: u64)
pub async fn cleanup_old_connections(&self, max_age_secs: u64)
Reap idle bookkeeping entries on connectionless servers (UDP, raw IP, link-level): their “connections” are per-remote-address records that nothing ever closes, so staleness is the only signal.
Connection-oriented servers are skipped on purpose. This used to run
over every server, and an idle TCP-style connection — a telnet peer
whose line was parked ten seconds for a human’s manual answer, a BGP
session between keepalives — was evicted from the state map and shown
as (closed) while its socket was alive; every later stat update and
the real close then targeted an entry that was already gone. Which
servers qualify comes from ProtocolMetadataV2::connectionless, so a
protocol the registry does not know is left alone.
Sourcepub async fn cleanup_closed_connections(&self, max_age_secs: u64)
pub async fn cleanup_closed_connections(&self, max_age_secs: u64)
Cleanup old closed connections (removes connections that have been closed for more than max_age_secs)
Sourcepub async fn cleanup_old_servers(&self, max_age_secs: u64)
pub async fn cleanup_old_servers(&self, max_age_secs: u64)
Cleanup old stopped/error servers (removes servers that have been stopped/error for more than max_age_secs)
Reaping a server here runs the same teardown as Self::remove_server:
background tasks aborted, scoped scheduled tasks cancelled. It previously
dropped the map entry alone, which detached (rather than aborted) whatever
the server was still running and left its scheduled tasks firing.
Must be driven by some loop or it never runs. The TUI ticks it; MCP mode has
its own reaper (mcp_stdio::tools::spawn_state_reaper), without which an
LLM-initiated close_server left entries in AppState forever.
Sourcepub async fn add_connection_to_server(
&self,
server_id: ServerId,
connection: ConnectionState,
)
pub async fn add_connection_to_server( &self, server_id: ServerId, connection: ConnectionState, )
Add a connection to a specific server
Sourcepub async fn close_connection_on_server(
&self,
server_id: ServerId,
connection_id: ConnectionId,
)
pub async fn close_connection_on_server( &self, server_id: ServerId, connection_id: ConnectionId, )
Mark a connection as closed (instead of removing it immediately)
Sourcepub async fn remove_connection_from_server(
&self,
server_id: ServerId,
connection_id: ConnectionId,
)
pub async fn remove_connection_from_server( &self, server_id: ServerId, connection_id: ConnectionId, )
Remove a connection from a specific server (used by cleanup task)
Sourcepub async fn get_recent_connections(
&self,
server_id: ServerId,
) -> Vec<ClosedConnectionSummary>
pub async fn get_recent_connections( &self, server_id: ServerId, ) -> Vec<ClosedConnectionSummary>
Recently closed connections for a server, newest first. Empty when the server does not exist.
Sourcepub async fn get_proxy_filter_config(
&self,
server_id: ServerId,
) -> Option<ProxyFilterConfig>
pub async fn get_proxy_filter_config( &self, server_id: ServerId, ) -> Option<ProxyFilterConfig>
Get proxy filter configuration for a server
Sourcepub async fn set_proxy_filter_config(
&self,
server_id: ServerId,
config: ProxyFilterConfig,
)
pub async fn set_proxy_filter_config( &self, server_id: ServerId, config: ProxyFilterConfig, )
Set proxy filter configuration for a server
Sourcepub async fn update_proxy_filter_config(
&self,
server_id: ServerId,
update_fn: impl FnOnce(&mut ProxyFilterConfig),
)
pub async fn update_proxy_filter_config( &self, server_id: ServerId, update_fn: impl FnOnce(&mut ProxyFilterConfig), )
Update proxy filter configuration by merging with existing config
Sourcepub async fn get_socks5_filter_config(
&self,
server_id: ServerId,
) -> Option<Socks5FilterConfig>
pub async fn get_socks5_filter_config( &self, server_id: ServerId, ) -> Option<Socks5FilterConfig>
Get SOCKS5 filter configuration for a server
Sourcepub async fn set_socks5_filter_config(
&self,
server_id: ServerId,
config: Socks5FilterConfig,
)
pub async fn set_socks5_filter_config( &self, server_id: ServerId, config: Socks5FilterConfig, )
Set SOCKS5 filter configuration for a server
Sourcepub async fn update_socks5_target(
&self,
server_id: ServerId,
connection_id: ConnectionId,
target_addr: Option<String>,
username: Option<String>,
)
pub async fn update_socks5_target( &self, server_id: ServerId, connection_id: ConnectionId, target_addr: Option<String>, username: Option<String>, )
Update SOCKS5 connection target address
Sourcepub async fn update_imap_session_state(
&self,
server_id: ServerId,
connection_id: ConnectionId,
session_state: ImapSessionState,
)
pub async fn update_imap_session_state( &self, server_id: ServerId, connection_id: ConnectionId, session_state: ImapSessionState, )
Update IMAP connection session state
Sourcepub async fn update_imap_connection_state(
&self,
server_id: ServerId,
connection_id: ConnectionId,
session_state: Option<ImapSessionState>,
authenticated_user: Option<Option<String>>,
selected_mailbox: Option<Option<String>>,
mailbox_read_only: Option<bool>,
)
pub async fn update_imap_connection_state( &self, server_id: ServerId, connection_id: ConnectionId, session_state: Option<ImapSessionState>, authenticated_user: Option<Option<String>>, selected_mailbox: Option<Option<String>>, mailbox_read_only: Option<bool>, )
Update IMAP connection full state (session, user, mailbox)
Sourcepub async fn get_imap_connection_state(
&self,
server_id: ServerId,
connection_id: ConnectionId,
) -> Option<(ImapSessionState, Option<String>, Option<String>)>
pub async fn get_imap_connection_state( &self, server_id: ServerId, connection_id: ConnectionId, ) -> Option<(ImapSessionState, Option<String>, Option<String>)>
Get IMAP connection state
Sourcepub async fn update_imap_protocol_state(
&self,
server_id: ServerId,
connection_id: ConnectionId,
protocol_state: ProtocolState,
)
pub async fn update_imap_protocol_state( &self, server_id: ServerId, connection_id: ConnectionId, protocol_state: ProtocolState, )
Update IMAP protocol state (Idle/Processing/Accumulating)
Sourcepub async fn update_connection_stats(
&self,
server_id: ServerId,
connection_id: ConnectionId,
bytes_received: Option<u64>,
bytes_sent: Option<u64>,
packets_received: Option<u64>,
packets_sent: Option<u64>,
)
pub async fn update_connection_stats( &self, server_id: ServerId, connection_id: ConnectionId, bytes_received: Option<u64>, bytes_sent: Option<u64>, packets_received: Option<u64>, packets_sent: Option<u64>, )
Update connection stats (bytes/packets)
Sourcepub async fn update_connection_status(
&self,
server_id: ServerId,
connection_id: ConnectionId,
status: ConnectionStatus,
)
pub async fn update_connection_status( &self, server_id: ServerId, connection_id: ConnectionId, status: ConnectionStatus, )
Update connection status
Sourcepub async fn update_vnc_connection_auth(
&self,
server_id: ServerId,
connection_id: ConnectionId,
authenticated: bool,
username: Option<String>,
)
pub async fn update_vnc_connection_auth( &self, server_id: ServerId, connection_id: ConnectionId, authenticated: bool, username: Option<String>, )
Update VNC connection authentication status
Sourcepub async fn update_bitcoin_connection_info(
&self,
server_id: ServerId,
connection_id: ConnectionId,
last_message_type: String,
)
pub async fn update_bitcoin_connection_info( &self, server_id: ServerId, connection_id: ConnectionId, last_message_type: String, )
Update Bitcoin connection info
Sourcepub async fn update_tftp_connection_block(
&self,
server_id: ServerId,
connection_id: ConnectionId,
block_number: u16,
block_bytes: usize,
)
pub async fn update_tftp_connection_block( &self, server_id: ServerId, connection_id: ConnectionId, block_number: u16, block_bytes: usize, )
Update TFTP connection block number and total bytes
Sourcepub async fn get_vnc_write_half(
&self,
_connection_id: ConnectionId,
) -> Option<Arc<Mutex<WriteHalf<TcpStream>>>>
pub async fn get_vnc_write_half( &self, _connection_id: ConnectionId, ) -> Option<Arc<Mutex<WriteHalf<TcpStream>>>>
Get VNC write half for sending framebuffer updates
Note: This method is deprecated. Write halves are now managed locally within protocol modules and not stored in centralized state.
Sourcepub async fn add_client(&self, client: ClientInstance) -> ClientId
pub async fn add_client(&self, client: ClientInstance) -> ClientId
Add a new client instance and return its ID
Sourcepub async fn disconnect_client(&self, id: ClientId) -> bool
pub async fn disconnect_client(&self, id: ClientId) -> bool
Remove a client instance, aborting every background task it owns.
Dropping a JoinHandle only DETACHES the task in Tokio — it keeps running,
keeps its socket open and keeps calling the LLM. Every handle registered via
Self::register_client_task is therefore aborted explicitly here, which is
what makes stop_client actually stop a client rather than just forgetting it.
Disconnect a client but KEEP its row, so it can be reconnected later.
Aborts the connection tasks (which closes the socket), drops the command handle, and marks the client Disconnected. Scheduled tasks and configuration survive — this is “hang up”, not “remove”.
pub async fn remove_client(&self, id: ClientId) -> Option<ClientInstance>
Sourcepub fn register_client_task(
&self,
id: ClientId,
handle: JoinHandle<()>,
) -> impl Future<Output = ()> + Send + '_
pub fn register_client_task( &self, id: ClientId, handle: JoinHandle<()>, ) -> impl Future<Output = ()> + Send + '_
Register a background task owned by a client so it can be aborted on stop.
Client connect() implementations call this with the JoinHandle of every
task they spawn — read loop, transport driver, in-flight request — right
after spawning it. Like register_server_task, handles accumulate: a
client that spawns three tasks gets all three aborted, none silently dropped.
If the client is already gone (raced with stop_client), the task is aborted
on the spot so it cannot outlive its owner.
Dropping its future, even before polling or while waiting for the state
lock, aborts the child until the registry has taken ownership.
Sourcepub async fn client_task_count(&self, id: ClientId) -> usize
pub async fn client_task_count(&self, id: ClientId) -> usize
Number of background tasks currently tracked for a client
Sourcepub async fn try_consume_client_llm_call(
&self,
id: ClientId,
) -> Result<u32, String>
pub async fn try_consume_client_llm_call( &self, id: ClientId, ) -> Result<u32, String>
Consume one LLM call from a client’s budget.
Returns Ok(calls_used) while the client is under its cap, and Err(message)
once the cap is reached. Clients hand-roll their own event loops and at least
one of them (DNS) could re-enter the LLM path indefinitely; an unbounded loop
burns real money against a paid endpoint, so the budget is a hard stop rather
than a warning.
The limit is per client session (not per event) and is configurable via
Self::set_client_llm_call_limit or NETGET_CLIENT_LLM_CALL_LIMIT
(0 disables the cap entirely).
Sourcepub async fn get_client_llm_calls(&self, id: ClientId) -> u32
pub async fn get_client_llm_calls(&self, id: ClientId) -> u32
Number of LLM calls a client has consumed so far
Sourcepub async fn get_client_llm_call_limit(&self) -> u32
pub async fn get_client_llm_call_limit(&self) -> u32
Get the per-client LLM call cap (0 = unlimited)
Sourcepub async fn set_client_llm_call_limit(&self, limit: u32)
pub async fn set_client_llm_call_limit(&self, limit: u32)
Set the per-client LLM call cap (0 = unlimited)
Sourcepub async fn get_client(&self, id: ClientId) -> Option<ClientInstance>
pub async fn get_client(&self, id: ClientId) -> Option<ClientInstance>
Get a client instance (cloned)
Sourcepub async fn get_all_client_ids(&self) -> Vec<ClientId>
pub async fn get_all_client_ids(&self) -> Vec<ClientId>
Get all client IDs
Sourcepub async fn get_all_clients(&self) -> Vec<ClientInstance>
pub async fn get_all_clients(&self) -> Vec<ClientInstance>
Get all clients (cloned)
Sourcepub async fn update_client_status(&self, id: ClientId, status: ClientStatus)
pub async fn update_client_status(&self, id: ClientId, status: ClientStatus)
Update client status
Sourcepub async fn get_instruction_for_client(
&self,
client_id: ClientId,
) -> Option<String>
pub async fn get_instruction_for_client( &self, client_id: ClientId, ) -> Option<String>
Get instruction for a specific client
Sourcepub async fn set_instruction_for_client(
&self,
client_id: ClientId,
instruction: String,
)
pub async fn set_instruction_for_client( &self, client_id: ClientId, instruction: String, )
Set instruction for a specific client
Sourcepub async fn get_memory_for_client(&self, client_id: ClientId) -> Option<String>
pub async fn get_memory_for_client(&self, client_id: ClientId) -> Option<String>
Get memory for a specific client
Sourcepub async fn set_memory_for_client(&self, client_id: ClientId, memory: String)
pub async fn set_memory_for_client(&self, client_id: ClientId, memory: String)
Set memory for a specific client
Sourcepub async fn append_memory_for_client(&self, client_id: ClientId, text: String)
pub async fn append_memory_for_client(&self, client_id: ClientId, text: String)
Append to memory for a specific client
Sourcepub async fn get_protocol_name_for_client(
&self,
client_id: ClientId,
) -> Option<String>
pub async fn get_protocol_name_for_client( &self, client_id: ClientId, ) -> Option<String>
Get protocol name for a client
Sourcepub async fn with_client_mut<F, R>(
&self,
client_id: ClientId,
f: F,
) -> Option<R>where
F: FnOnce(&mut ClientInstance) -> R,
pub async fn with_client_mut<F, R>(
&self,
client_id: ClientId,
f: F,
) -> Option<R>where
F: FnOnce(&mut ClientInstance) -> R,
Execute a closure with mutable access to a client
Sourcepub async fn set_client_event_handler_config(
&self,
client_id: ClientId,
config: Option<EventHandlerConfig>,
)
pub async fn set_client_event_handler_config( &self, client_id: ClientId, config: Option<EventHandlerConfig>, )
Update event handler configuration for a client
Sourcepub async fn get_client_event_handler_config(
&self,
client_id: ClientId,
) -> Option<EventHandlerConfig>
pub async fn get_client_event_handler_config( &self, client_id: ClientId, ) -> Option<EventHandlerConfig>
Get event handler configuration for a client
Sourcepub async fn cleanup_old_clients(&self, max_age_secs: u64)
pub async fn cleanup_old_clients(&self, max_age_secs: u64)
Cleanup old disconnected clients (removes clients that have been disconnected for more than max_age_secs)
Sourcepub async fn add_easy_instance(&self, easy_instance: EasyInstance) -> EasyId
pub async fn add_easy_instance(&self, easy_instance: EasyInstance) -> EasyId
Add a new easy protocol instance
Sourcepub async fn remove_easy_instance(&self, id: EasyId) -> Option<EasyInstance>
pub async fn remove_easy_instance(&self, id: EasyId) -> Option<EasyInstance>
Remove an easy protocol instance
Sourcepub async fn link_server_to_easy(&self, server_id: ServerId, easy_id: EasyId)
pub async fn link_server_to_easy(&self, server_id: ServerId, easy_id: EasyId)
Link an underlying server to an easy protocol instance (for event routing)
Sourcepub async fn link_client_to_easy(&self, client_id: ClientId, easy_id: EasyId)
pub async fn link_client_to_easy(&self, client_id: ClientId, easy_id: EasyId)
Link an underlying client to an easy protocol instance (for event routing)
Sourcepub async fn get_easy_for_server(&self, server_id: ServerId) -> Option<EasyId>
pub async fn get_easy_for_server(&self, server_id: ServerId) -> Option<EasyId>
Get easy ID for a given server ID (returns None if server is not managed by an easy protocol)
Sourcepub async fn get_easy_for_client(&self, client_id: ClientId) -> Option<EasyId>
pub async fn get_easy_for_client(&self, client_id: ClientId) -> Option<EasyId>
Get easy ID for a given client ID (returns None if client is not managed by an easy protocol)
Sourcepub async fn get_easy_instance(&self, id: EasyId) -> Option<EasyInstance>
pub async fn get_easy_instance(&self, id: EasyId) -> Option<EasyInstance>
Get easy protocol instance
Sourcepub async fn update_easy_status(&self, id: EasyId, status: EasyStatus)
pub async fn update_easy_status(&self, id: EasyId, status: EasyStatus)
Update easy protocol status
Sourcepub async fn get_all_easy_instances(&self) -> Vec<EasyInstance>
pub async fn get_all_easy_instances(&self) -> Vec<EasyInstance>
Get all easy protocol instances
Sourcepub async fn with_easy_mut<F, R>(&self, easy_id: EasyId, f: F) -> Option<R>where
F: FnOnce(&mut EasyInstance) -> R,
pub async fn with_easy_mut<F, R>(&self, easy_id: EasyId, f: F) -> Option<R>where
F: FnOnce(&mut EasyInstance) -> R,
Execute a closure with mutable access to an easy instance
Sourcepub async fn get_first_protocol_name(&self) -> Option<String>
pub async fn get_first_protocol_name(&self) -> Option<String>
Get the first server’s protocol name (for backwards compat)
Sourcepub async fn get_first_instruction(&self) -> String
pub async fn get_first_instruction(&self) -> String
Get the first server’s instruction (for backwards compat)
Sourcepub async fn get_first_memory(&self) -> String
pub async fn get_first_memory(&self) -> String
Get the first server’s memory (for backwards compat)
Sourcepub async fn get_first_server_id(&self) -> Option<ServerId>
pub async fn get_first_server_id(&self) -> Option<ServerId>
Get the first server’s ID (for backwards compat)
Sourcepub async fn get_first_client_id(&self) -> Option<ClientId>
pub async fn get_first_client_id(&self) -> Option<ClientId>
Get the first client’s ID (for backwards compat)
Sourcepub async fn get_local_addr(&self) -> Option<SocketAddr>
pub async fn get_local_addr(&self) -> Option<SocketAddr>
Get local address of first server (for backwards compat)
Sourcepub async fn with_server_mut<F, R>(
&self,
server_id: ServerId,
f: F,
) -> Option<R>where
F: FnOnce(&mut ServerInstance) -> R,
pub async fn with_server_mut<F, R>(
&self,
server_id: ServerId,
f: F,
) -> Option<R>where
F: FnOnce(&mut ServerInstance) -> R,
Execute a closure with mutable access to a server
Sourcepub async fn add_task(&self, task: ScheduledTask) -> TaskId
pub async fn add_task(&self, task: ScheduledTask) -> TaskId
Add a new scheduled task
Sourcepub async fn get_task(&self, id_or_name: &str) -> Option<ScheduledTask>
pub async fn get_task(&self, id_or_name: &str) -> Option<ScheduledTask>
Get a task by ID or name
Sourcepub async fn remove_task(&self, id: TaskId) -> Option<ScheduledTask>
pub async fn remove_task(&self, id: TaskId) -> Option<ScheduledTask>
Remove a task
Sourcepub async fn spawn_scheduled_task<F>(&self, id: TaskId, future: F) -> bool
pub async fn spawn_scheduled_task<F>(&self, id: TaskId, future: F) -> bool
Start a claimed task while holding its ownership lock. Removal cannot race between spawn and registration; a previously removed claim is skipped.
Sourcepub async fn get_all_tasks(&self) -> Vec<ScheduledTask>
pub async fn get_all_tasks(&self) -> Vec<ScheduledTask>
Get all tasks
Sourcepub async fn claim_due_tasks(&self) -> Vec<ScheduledTask>
pub async fn claim_due_tasks(&self) -> Vec<ScheduledTask>
Atomically claim scheduled tasks whose deadline has arrived.
A separate snapshot and status update lets concurrent timer ticks both execute the same task. Mark each task while holding the selection lock.
Sourcepub async fn get_server_tasks(&self, server_id: ServerId) -> Vec<ScheduledTask>
pub async fn get_server_tasks(&self, server_id: ServerId) -> Vec<ScheduledTask>
Get tasks for a specific server
Sourcepub async fn get_connection_tasks(
&self,
server_id: ServerId,
connection_id: ConnectionId,
) -> Vec<ScheduledTask>
pub async fn get_connection_tasks( &self, server_id: ServerId, connection_id: ConnectionId, ) -> Vec<ScheduledTask>
Get tasks for a specific connection
Sourcepub async fn update_task_status(&self, id: TaskId, status: TaskStatus)
pub async fn update_task_status(&self, id: TaskId, status: TaskStatus)
Update task status
Sourcepub async fn update_task_next_execution(&self, id: TaskId, next: Instant)
pub async fn update_task_next_execution(&self, id: TaskId, next: Instant)
Update task next execution time
Sourcepub async fn record_task_execution(
&self,
id: TaskId,
result: &TaskExecutionResult,
)
pub async fn record_task_execution( &self, id: TaskId, result: &TaskExecutionResult, )
Record task execution result
Sourcepub async fn cleanup_server_tasks(&self, server_id: ServerId)
pub async fn cleanup_server_tasks(&self, server_id: ServerId)
Clean up the scheduled tasks associated with a server.
Both server-scoped tasks and the connection-scoped tasks of that server’s connections are removed: a connection cannot outlive its server, so leaving its tasks behind leaves them firing against a server that no longer exists.
Callers rarely need this — Self::remove_server and
Self::cleanup_old_servers already do it. It stays public for the TUI,
which marks a server Stopped and leaves the entry in place for the reaper.
Sourcepub async fn cleanup_connection_tasks(
&self,
server_id: ServerId,
connection_id: ConnectionId,
)
pub async fn cleanup_connection_tasks( &self, server_id: ServerId, connection_id: ConnectionId, )
Clean up tasks associated with a connection
Sourcepub async fn cleanup_client_tasks(&self, client_id: ClientId)
pub async fn cleanup_client_tasks(&self, client_id: ClientId)
Clean up tasks associated with a client
Sourcepub async fn register_conversation(
&self,
id: String,
source: ConversationSource,
details: String,
)
pub async fn register_conversation( &self, id: String, source: ConversationSource, details: String, )
Register a new conversation
Sourcepub async fn end_conversation(&self, id: &str)
pub async fn end_conversation(&self, id: &str)
Mark a conversation as ended
Sourcepub async fn get_active_conversations(&self) -> Vec<ConversationInfo>
pub async fn get_active_conversations(&self) -> Vec<ConversationInfo>
Get all active conversations and recently-completed ones (within 1 second)
Sourcepub async fn get_input_conversations(&self) -> Vec<ConversationInfo>
pub async fn get_input_conversations(&self) -> Vec<ConversationInfo>
Get conversations for the “Running” column (User + Global tasks)
Sourcepub async fn cleanup_old_conversations(&self)
pub async fn cleanup_old_conversations(&self)
Clean up old completed conversations (older than 1 second)
Sourcepub async fn get_or_create_user_conversation_state(
&self,
) -> Arc<Mutex<ConversationState>> ⓘ
pub async fn get_or_create_user_conversation_state( &self, ) -> Arc<Mutex<ConversationState>> ⓘ
Get or create the user conversation state
Sourcepub async fn clear_user_conversation_history(&self)
pub async fn clear_user_conversation_history(&self)
Clear user conversation history
Sourcepub async fn get_user_conversation_history(&self) -> Option<String>
pub async fn get_user_conversation_history(&self) -> Option<String>
Get formatted conversation history for prompts
Sourcepub async fn record_access_log(
&self,
owner: AccessLogOwner,
protocol: &str,
connection_id: Option<u32>,
event_type: &str,
request: Value,
response: Vec<Value>,
) -> u64
pub async fn record_access_log( &self, owner: AccessLogOwner, protocol: &str, connection_id: Option<u32>, event_type: &str, request: Value, response: Vec<Value>, ) -> u64
Record a request/response access-log entry (ring buffer, oldest dropped past capacity). Returns the assigned entry id.
Sourcepub async fn access_log_total(&self) -> u64
pub async fn access_log_total(&self) -> u64
How many access-log entries have ever been recorded — one per network event a server
or client handled (whatever answered it: handler, model or operator), plus one per
injected action. Unlike the ring buffer this never shrinks, so it is a monotonic count
of handled events for the life of the process (--exit-after-events reads it).
Sourcepub async fn list_access_logs(
&self,
limit: Option<usize>,
) -> Vec<AccessLogEntry>
pub async fn list_access_logs( &self, limit: Option<usize>, ) -> Vec<AccessLogEntry>
Return the most recent access-log entries, newest first (up to limit).
Pass None for the full retained buffer.
Sourcepub async fn list_access_logs_for(
&self,
owner: Option<AccessLogOwner>,
limit: Option<usize>,
) -> Vec<AccessLogEntry>
pub async fn list_access_logs_for( &self, owner: Option<AccessLogOwner>, limit: Option<usize>, ) -> Vec<AccessLogEntry>
Return the most recent access-log entries for one instance (or all,
with owner: None), newest first (up to limit).
Sourcepub async fn get_access_log(&self, id: u64) -> Option<AccessLogEntry>
pub async fn get_access_log(&self, id: u64) -> Option<AccessLogEntry>
Look up a single access-log entry by id.
Sourcepub async fn record_llm_tokens(&self, input_tokens: u64, output_tokens: u64)
pub async fn record_llm_tokens(&self, input_tokens: u64, output_tokens: u64)
Record LLM call tokens
Sourcepub async fn get_llm_stats(&self) -> (u64, u64, u64)
pub async fn get_llm_stats(&self) -> (u64, u64, u64)
Get LLM token statistics
Sourcepub async fn reset_llm_stats(&self)
pub async fn reset_llm_stats(&self)
Reset LLM token statistics
Sourcepub async fn create_database(
&self,
name: String,
path: String,
owner: DatabaseOwner,
init_sql: Option<&str>,
) -> Result<DatabaseId>
pub async fn create_database( &self, name: String, path: String, owner: DatabaseOwner, init_sql: Option<&str>, ) -> Result<DatabaseId>
Create a new database
Sourcepub async fn execute_sql(
&self,
db_id: DatabaseId,
sql: &str,
) -> Result<QueryResult>
pub async fn execute_sql( &self, db_id: DatabaseId, sql: &str, ) -> Result<QueryResult>
Execute a SQL query on a database
Sourcepub async fn get_all_databases(&self) -> Vec<DatabaseInstance>
pub async fn get_all_databases(&self) -> Vec<DatabaseInstance>
Get all databases
Sourcepub async fn get_database(&self, db_id: DatabaseId) -> Option<DatabaseInstance>
pub async fn get_database(&self, db_id: DatabaseId) -> Option<DatabaseInstance>
Get a database by ID
Sourcepub async fn delete_database(&self, db_id: DatabaseId) -> Result<()>
pub async fn delete_database(&self, db_id: DatabaseId) -> Result<()>
Delete a database
Sourcepub async fn get_databases_by_server(
&self,
server_id: ServerId,
) -> Vec<DatabaseInstance>
pub async fn get_databases_by_server( &self, server_id: ServerId, ) -> Vec<DatabaseInstance>
Get databases owned by a server
Sourcepub async fn get_databases_by_client(
&self,
client_id: ClientId,
) -> Vec<DatabaseInstance>
pub async fn get_databases_by_client( &self, client_id: ClientId, ) -> Vec<DatabaseInstance>
Get databases owned by a client
Sourcepub async fn cleanup_databases_for_server(
&self,
server_id: ServerId,
) -> Result<()>
pub async fn cleanup_databases_for_server( &self, server_id: ServerId, ) -> Result<()>
Delete all databases owned by a server (called when server closes)
Sourcepub async fn cleanup_databases_for_client(
&self,
client_id: ClientId,
) -> Result<()>
pub async fn cleanup_databases_for_client( &self, client_id: ClientId, ) -> Result<()>
Delete all databases owned by a client (called when client disconnects)
Sourcepub async fn add_server_with_id(&self, server: ServerInstance)
pub async fn add_server_with_id(&self, server: ServerInstance)
Test-only helper to add a server with a specific ID (bypasses auto-increment)
WARNING: This method is intended for testing only. In production code, use add_server()
which properly assigns server IDs.
Sourcepub async fn set_tor_client(
&self,
client_id: ClientId,
tor_client: Arc<TorClient<PreferredRuntime>>,
)
pub async fn set_tor_client( &self, client_id: ClientId, tor_client: Arc<TorClient<PreferredRuntime>>, )
Store Tor client instance for directory queries
Sourcepub async fn get_tor_client(
&self,
client_id: ClientId,
) -> Option<Arc<TorClient<PreferredRuntime>>>
pub async fn get_tor_client( &self, client_id: ClientId, ) -> Option<Arc<TorClient<PreferredRuntime>>>
Get Tor client instance by client ID
Sourcepub async fn remove_tor_client(&self, client_id: ClientId)
pub async fn remove_tor_client(&self, client_id: ClientId)
Remove Tor client instance (called when client closes)
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for AppState
impl !UnwindSafe for AppState
impl Freeze for AppState
impl Send for AppState
impl Sync for AppState
impl Unpin for AppState
impl UnsafeUnpin for AppState
Blanket Implementations§
Source§impl<Source> AccessAs for Source
impl<Source> AccessAs for Source
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Choices> CoproductSubsetter<CNil, HNil> for Choices
impl<Choices> CoproductSubsetter<CNil, HNil> for Choices
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoAnyArc for T
impl<T> IntoAnyArc for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Requestimpl<T> OrderedContainer<T> for Twhere
T: Clone,
Source§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian().Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.