pub struct LanDiscoveryController {
slot: Arc<RwLock<Option<Arc<LanDiscovery>>>>,
instance_id: String,
hostname: String,
version: String,
port: u16,
auth_key: String,
event_bus: Arc<EventBus>,
agent_cache: RwLock<HashMap<String, LanCacheEntry>>,
}Expand description
Controller for live start/stop of LanDiscovery in response to setting changes.
Owns the daemon slot plus the start arguments, so toggling
network:lan_discovery from the UI (or from an external edit of
settings.json) can start or stop the daemon without restarting the
process.
Spec: specs/lan-discovery-toggle.md
Fields§
§slot: Arc<RwLock<Option<Arc<LanDiscovery>>>>§instance_id: String§hostname: String§version: String§port: u16§auth_key: String§event_bus: Arc<EventBus>§agent_cache: RwLock<HashMap<String, LanCacheEntry>>Short-lived cache mapping agent_id → (peer_url, auth_key). Entries expire after LAN_AGENT_CACHE_TTL_SECS to handle agent migration between peers.
Implementations§
Source§impl LanDiscoveryController
impl LanDiscoveryController
pub fn new( instance_id: String, hostname: String, version: String, port: u16, event_bus: Arc<EventBus>, auth_key: String, ) -> Self
Sourcepub async fn find_agent(
&self,
agent_id: &str,
http: &Client,
) -> Option<(String, String)>
pub async fn find_agent( &self, agent_id: &str, http: &Client, ) -> Option<(String, String)>
Query LAN peers for which one hosts agent_id. Returns (peer_url, auth_key) for the first peer that responds 2xx to the agent-lookup
endpoint. Results — both positive and negative — are cached for
LAN_AGENT_CACHE_TTL_SECS seconds to avoid a blocking peer fan-out on
every inject for cloud-only agents.
Security: auth_key is broadcast in the mDNS TXT record. This is
intentional and matches the same trust assumption as tier-2 loopback
forwarding — LAN traffic is trusted (private network). Anyone on the LAN
who can already intercept mDNS multicast can intercept the HTTP traffic
too, so the key adds no exposure beyond what already exists.
Sourcepub fn evict_agent(&self, agent_id: &str)
pub fn evict_agent(&self, agent_id: &str)
Evict a stale cache entry (e.g. after a forward to that peer failed).
Sourcepub fn apply(&self, enabled: bool)
pub fn apply(&self, enabled: bool)
Idempotent: starts the daemon when enabled and not running, stops it
when !enabled and running. Re-entrant safe.
Holds the slot’s write lock for the entire check-and-modify transaction
to avoid a TOCTOU race between the is_running read and the slot
mutation. apply() is called from toggle clicks and setting writes —
low frequency — so briefly blocking concurrent peer-list reads is
acceptable. LanDiscovery::start() and Drop are both fast (mDNS
daemon construction + service register/unregister are local socket ops).
Sourcepub fn get_instances(&self) -> Vec<LanInstance>
pub fn get_instances(&self) -> Vec<LanInstance>
Read the current peer list. Returns empty when the daemon is not running (discovery disabled or start failed).
Auto Trait Implementations§
impl !Freeze for LanDiscoveryController
impl !RefUnwindSafe for LanDiscoveryController
impl Send for LanDiscoveryController
impl Sync for LanDiscoveryController
impl Unpin for LanDiscoveryController
impl !UnwindSafe for LanDiscoveryController
Blanket Implementations§
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
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§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>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§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>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§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.§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.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
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 more