fix(ci): close capability races and green audit
This commit is contained in:
@@ -83,6 +83,7 @@ pub(crate) struct CapsInner {
|
||||
event_queue: Mutex<Option<EventQueueClient>>,
|
||||
seed_task: Mutex<Option<SeedTask>>,
|
||||
events: Arc<CapabilitiesEventState>,
|
||||
seed_request_completed: AtomicBool,
|
||||
disconnected: AtomicBool,
|
||||
}
|
||||
|
||||
@@ -193,6 +194,7 @@ impl Caps {
|
||||
event_queue: Mutex::new(None),
|
||||
seed_task: Mutex::new(None),
|
||||
events: Arc::new(CapabilitiesEventState::default()),
|
||||
seed_request_completed: AtomicBool::new(false),
|
||||
disconnected: AtomicBool::new(false),
|
||||
});
|
||||
start_seed_task(&inner)?;
|
||||
@@ -257,9 +259,7 @@ impl Caps {
|
||||
}
|
||||
|
||||
pub(crate) fn seed_request_finished(&self) -> bool {
|
||||
mutex(&self.inner.seed_task)
|
||||
.as_ref()
|
||||
.is_none_or(|task| task.handle.is_finished())
|
||||
self.inner.seed_request_completed.load(Ordering::Acquire)
|
||||
}
|
||||
|
||||
pub fn disconnect(&self, immediate: bool) -> Result<(), Error> {
|
||||
@@ -379,10 +379,14 @@ async fn run_seed_requests(weak: Weak<CapsInner>, cancellation: CancellationToke
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
finish_seed_request(&inner, simulator);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Ok((response, _)) if response.status_code == 404 => return,
|
||||
Ok((response, _)) if response.status_code == 404 => {
|
||||
finish_seed_request(&inner, simulator);
|
||||
return;
|
||||
}
|
||||
Err(Error::Cancelled) if cancellation.is_cancellation_requested() => return,
|
||||
Ok(_) | Err(_) => {}
|
||||
}
|
||||
@@ -461,10 +465,15 @@ async fn install_seed_response(
|
||||
let _ = simulator.features.set_features(None, Some(bytes), None);
|
||||
}
|
||||
cancellation.throw_if_cancellation_requested()?;
|
||||
inner.emit_capabilities_received(simulator.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn finish_seed_request(inner: &CapsInner, simulator: Simulator) {
|
||||
if !inner.seed_request_completed.swap(true, Ordering::AcqRel) {
|
||||
inner.emit_capabilities_received(simulator);
|
||||
}
|
||||
}
|
||||
|
||||
fn seed_retry_delay(uri: &Uri, retry: u32) -> Duration {
|
||||
let multiplier = 1_u32
|
||||
.checked_shl(retry.saturating_sub(1).min(30))
|
||||
|
||||
@@ -3962,6 +3962,12 @@ impl InventoryManager {
|
||||
if let Some(uri) = caps.capability_uri(name.to_owned())? {
|
||||
return Ok(Some(uri));
|
||||
}
|
||||
// Seed completion can race subscription registration. The completion
|
||||
// bit is published before the event, so this post-subscribe check
|
||||
// closes the lost-notification window without polling or sleeping.
|
||||
if caps.seed_request_finished() {
|
||||
return Ok(None);
|
||||
}
|
||||
let cancellation = cancellation_token.cancelled();
|
||||
futures_util::pin_mut!(receiver, cancellation);
|
||||
match select(receiver, cancellation).await {
|
||||
|
||||
Reference in New Issue
Block a user