Split oversized runtime modules + Async tests hardened

Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
Alexey
2026-08-30 09:39:25 +03:00
parent 281f63f940
commit 66f2b8889f
154 changed files with 25561 additions and 24915 deletions
+4 -4
View File
@@ -18,8 +18,8 @@ pub(crate) use status::{
};
// Admission fencing and registration-drain synchronization.
mod admission;
use admission::{OperatorAdmission, OperatorAdmissionRejection};
pub(super) use admission::OperatorRegistration;
use admission::{OperatorAdmission, OperatorAdmissionRejection};
// Mutable and published lifecycle state storage.
mod state;
use state::{ActiveDrain, OperatorLifecycleInner, OperatorSnapshot, WorkCounts};
@@ -246,9 +246,9 @@ impl WebProcessRuntime {
self.operator_lifecycle
.transition_locked(&mut inner, OperatorLifecycleState::Paused);
}
self.operator_lifecycle.admission.close(
OperatorAdmissionRejection::for_state(inner.state),
);
self.operator_lifecycle
.admission
.close(OperatorAdmissionRejection::for_state(inner.state));
self.operator_lifecycle.publish_locked(&inner);
}
self.operator_lifecycle
@@ -53,9 +53,7 @@ impl OperatorAdmissionRejection {
match self {
Self::Paused => crate::web::telemetry::WebRejectionReason::OperatorPaused,
Self::Draining => crate::web::telemetry::WebRejectionReason::OperatorDraining,
Self::ForceClosing => {
crate::web::telemetry::WebRejectionReason::OperatorForceClosing
}
Self::ForceClosing => crate::web::telemetry::WebRejectionReason::OperatorForceClosing,
Self::Drained => crate::web::telemetry::WebRejectionReason::OperatorDrained,
Self::RuntimeClosed => crate::web::telemetry::WebRejectionReason::RuntimeClosed,
}
@@ -90,7 +88,7 @@ impl OperatorAdmission {
loop {
if state & OPERATOR_ADMISSION_CLOSED != 0 {
return Err(
OperatorAdmissionRejection::from_admission_state(state).telemetry_reason(),
OperatorAdmissionRejection::from_admission_state(state).telemetry_reason()
);
}
if state & OPERATOR_REGISTRATION_COUNT == OPERATOR_REGISTRATION_COUNT {
@@ -113,15 +111,11 @@ impl OperatorAdmission {
let reason = (reason as usize) << OPERATOR_REJECTION_SHIFT;
let mut state = self.state.load(Ordering::Acquire);
loop {
let next = (state & OPERATOR_REGISTRATION_COUNT)
| OPERATOR_ADMISSION_CLOSED
| reason;
match self.state.compare_exchange_weak(
state,
next,
Ordering::AcqRel,
Ordering::Acquire,
) {
let next = (state & OPERATOR_REGISTRATION_COUNT) | OPERATOR_ADMISSION_CLOSED | reason;
match self
.state
.compare_exchange_weak(state, next, Ordering::AcqRel, Ordering::Acquire)
{
Ok(_) => return,
Err(observed) => state = observed,
}
+2 -5
View File
@@ -138,11 +138,8 @@ async fn drain_request_returns_after_registering_its_worker() {
let (runtime, generation) = test_runtime();
let registration = runtime.try_operator_admission().unwrap();
let drain_runtime = Arc::clone(&runtime);
let drain = tokio::spawn(async move {
drain_runtime
.drain_operator(Duration::from_secs(30))
.await
});
let drain =
tokio::spawn(async move { drain_runtime.drain_operator(Duration::from_secs(30)).await });
tokio::time::timeout(Duration::from_secs(1), async {
while runtime.operator_lifecycle_status().state != OperatorLifecycleState::Draining {
+5 -50
View File
@@ -515,53 +515,8 @@ impl WebProcessRuntime {
}
}
/// Opaque session-reference validation failure.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum SessionRefError {
/// The reference does not use the canonical versioned shape.
Invalid,
/// The reference belongs to another process runtime.
StaleInstance,
}
/// Tests immutable candidate fields before any optional state-lock read.
pub(super) fn immutable_matches(
session: &crate::web::session::WebSession,
index: &super::state::LiveSessionIndex,
filter: &SessionFilter,
) -> bool {
filter
.trace_session_id
.is_none_or(|value| value == session.trace_session_id())
&& filter
.client_ip
.is_none_or(|value| value == session.client_ip())
&& filter
.host
.as_deref()
.is_none_or(|value| value == session.profile_host())
&& filter
.user
.as_deref()
.is_none_or(|value| value == session.profile_user())
&& filter
.key_id
.as_deref()
.is_none_or(|value| session.key_id() == value)
&& filter
.carrier
.is_none_or(|value| value == session.carrier())
&& filter
.user_agent_id
.is_none_or(|value| index.user_agent_id == Some(value))
}
fn permits(semaphore: &Arc<tokio::sync::Semaphore>, capacity: usize) -> PermitStatus {
let available = semaphore.available_permits().min(capacity);
PermitStatus {
used: capacity.saturating_sub(available),
available,
capacity,
closed: semaphore.is_closed(),
}
}
// Opaque session references and immutable filter matching.
mod reference;
pub(crate) use reference::SessionRefError;
pub(super) use reference::immutable_matches;
use reference::permits;
+52
View File
@@ -0,0 +1,52 @@
use super::*;
/// Opaque session-reference validation failure.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum SessionRefError {
/// The reference does not use the canonical versioned shape.
Invalid,
/// The reference belongs to another process runtime.
StaleInstance,
}
/// Tests immutable candidate fields before any optional state-lock read.
pub(in crate::web::manager) fn immutable_matches(
session: &crate::web::session::WebSession,
index: &crate::web::manager::state::LiveSessionIndex,
filter: &SessionFilter,
) -> bool {
filter
.trace_session_id
.is_none_or(|value| value == session.trace_session_id())
&& filter
.client_ip
.is_none_or(|value| value == session.client_ip())
&& filter
.host
.as_deref()
.is_none_or(|value| value == session.profile_host())
&& filter
.user
.as_deref()
.is_none_or(|value| value == session.profile_user())
&& filter
.key_id
.as_deref()
.is_none_or(|value| session.key_id() == value)
&& filter
.carrier
.is_none_or(|value| value == session.carrier())
&& filter
.user_agent_id
.is_none_or(|value| index.user_agent_id == Some(value))
}
pub(super) fn permits(semaphore: &Arc<tokio::sync::Semaphore>, capacity: usize) -> PermitStatus {
let available = semaphore.available_permits().min(capacity);
PermitStatus {
used: capacity.saturating_sub(available),
available,
capacity,
closed: semaphore.is_closed(),
}
}