Implement native UDP transport reliability (#52)
Some checks failed
Native code generation / deterministic (push) Failing after 7m48s
Imaging and meshing gate / native (push) Failing after 17s
JPEG 2000 feature / linux (push) Failing after 58s
Skia feature / linux (push) Failing after 1m33s

This commit is contained in:
2026-08-09 11:39:59 +00:00
parent b413cd6f4d
commit c7777d42f5
13 changed files with 2593 additions and 214 deletions

View File

@@ -113,6 +113,7 @@ struct ClientRuntime {
state: AtomicU8,
cancellation: CancellationTokenSource,
services: Mutex<Vec<ServiceRegistration>>,
agent_throttle_sender: Mutex<Option<Arc<dyn crate::udp_transport::AgentThrottleSender>>>,
shutdown_complete: Condvar,
shutdown_wait: Mutex<()>,
}
@@ -132,6 +133,7 @@ impl ClientRuntime {
})
.collect(),
),
agent_throttle_sender: Mutex::new(None),
shutdown_complete: Condvar::new(),
shutdown_wait: Mutex::new(()),
}
@@ -200,6 +202,10 @@ impl ClientRuntime {
}
}
services.clear();
self.agent_throttle_sender
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.take();
let shutdown_wait = self
.shutdown_wait
.lock()
@@ -257,6 +263,41 @@ impl GridClient {
self.runtime.register(service)
}
/// Installs the network-owned callback used by mapped `AgentThrottle.Set`.
///
/// # Errors
///
/// Registration fails after client shutdown begins.
pub fn set_agent_throttle_sender(
&mut self,
sender: Arc<dyn crate::udp_transport::AgentThrottleSender>,
) -> Result<(), ClientCoreError> {
let mut registered = self
.runtime
.agent_throttle_sender
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let state = self.lifecycle_state();
if state != ClientLifecycleState::Active {
return Err(ClientCoreError::InvalidLifecycle {
operation: "register the agent throttle sender",
state,
});
}
*registered = Some(sender);
Ok(())
}
pub(crate) fn agent_throttle_sender(
&self,
) -> Option<Arc<dyn crate::udp_transport::AgentThrottleSender>> {
self.runtime
.agent_throttle_sender
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.clone()
}
pub(crate) fn shutdown(&self) -> Result<(), ClientCoreError> {
self.runtime.shutdown()
}