mirror of
https://github.com/telemt/telemt.git
synced 2026-09-16 15:34:13 +03:00
Split oversized runtime modules + Async tests hardened
Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user