Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions src/controller/core/admission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
admission::AdmissionPolicy,
slot::{AdmissionTransition, ReplaceAction, SlotPhase, SlotState},
},
events::{Event, EventKind},
events::{Event, EventKind, RejectionKind},
identity::TaskId,
reasons,
};
Expand Down Expand Up @@ -48,9 +48,14 @@ impl Controller {
Event::new(EventKind::ControllerRejected)
.with_task(spec.slot_name().to_owned())
.with_id(id)
.with_rejection_kind(RejectionKind::ControllerShuttingDown)
.with_reason(crate::reasons::CONTROLLER_SHUTTING_DOWN),
);
self.finalize_rejected(id, crate::reasons::CONTROLLER_SHUTTING_DOWN);
self.finalize_rejected(
id,
RejectionKind::ControllerShuttingDown,
crate::reasons::CONTROLLER_SHUTTING_DOWN,
);
return;
}

Expand All @@ -65,9 +70,14 @@ impl Controller {
Event::new(EventKind::ControllerRejected)
.with_task(Arc::clone(&slot_name))
.with_id(id)
.with_rejection_kind(RejectionKind::ControllerShuttingDown)
.with_reason(crate::reasons::CONTROLLER_SHUTTING_DOWN),
);
self.finalize_rejected(id, crate::reasons::CONTROLLER_SHUTTING_DOWN);
self.finalize_rejected(
id,
RejectionKind::ControllerShuttingDown,
crate::reasons::CONTROLLER_SHUTTING_DOWN,
);
return;
}

Expand Down Expand Up @@ -95,9 +105,10 @@ impl Controller {
Event::new(EventKind::ControllerRejected)
.with_task(Arc::clone(&slot_name))
.with_id(id)
.with_rejection_kind(RejectionKind::AdmissionFailed)
.with_reason(reason.clone()),
);
self.finalize_rejected(id, &reason);
self.finalize_rejected(id, RejectionKind::AdmissionFailed, &reason);
self.gc_if_idle(&slot_name, slot);
}
}
Expand Down Expand Up @@ -185,9 +196,10 @@ impl Controller {
Event::new(EventKind::ControllerRejected)
.with_task(Arc::clone(&slot_name))
.with_id(id)
.with_rejection_kind(RejectionKind::SlotBusy)
.with_reason(reason.clone()),
);
self.finalize_rejected(id, &reason);
self.finalize_rejected(id, RejectionKind::SlotBusy, &reason);
}
}
}
Expand Down Expand Up @@ -342,9 +354,10 @@ impl Controller {
Event::new(EventKind::ControllerRejected)
.with_task(Arc::clone(slot_name))
.with_id(next_id)
.with_rejection_kind(RejectionKind::AdmissionFailed)
.with_reason(reason.clone()),
);
self.finalize_rejected(next_id, &reason);
self.finalize_rejected(next_id, RejectionKind::AdmissionFailed, &reason);
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/controller/core/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use tokio::{sync::oneshot, task::JoinSet};

use crate::{
RuntimeError,
events::{Event, EventKind},
events::{Event, EventKind, RejectionKind},
identity::TaskId,
};

Expand Down Expand Up @@ -108,9 +108,14 @@ impl Controller {
Event::new(EventKind::ControllerRejected)
.with_task(Arc::clone(&slot_name))
.with_id(id)
.with_rejection_kind(RejectionKind::RemovedFromQueue)
.with_reason(crate::reasons::REMOVED_FROM_QUEUE),
);
self.finalize_rejected(id, crate::reasons::REMOVED_FROM_QUEUE);
self.finalize_rejected(
id,
RejectionKind::RemovedFromQueue,
crate::reasons::REMOVED_FROM_QUEUE,
);
self.gc_if_idle(&slot_name, slot);
return true;
}
Expand Down
71 changes: 34 additions & 37 deletions src/controller/core/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ use std::{future::Future, sync::Arc};
use tokio::task::JoinSet;
use tokio_util::sync::CancellationToken;

use crate::{
controller::error::ControllerError,
events::{Event, EventKind},
};
use crate::{controller::error::ControllerError, events::Event};

use super::{Controller, ControllerCommand, ControllerTask};

Expand All @@ -31,18 +28,16 @@ impl Controller {
match crate::core::panic_guard::guarded(self.run_inner(token)).await {
Ok(Ok(())) => {}
Ok(Err(error)) => {
self.bus.publish(
Event::new(EventKind::ControllerRejected)
.with_task("controller")
.with_reason(format!("controller_loop_exited: {error}")),
);
self.bus.publish(Event::runtime_failure(
"controller",
format!("controller_loop_exited: {error}"),
));
}
Err(panic) => {
self.bus.publish(
Event::new(EventKind::ControllerRejected)
.with_task("controller")
.with_reason(format!("controller_loop_panicked: {panic}")),
);
self.bus.publish(Event::runtime_failure(
"controller",
format!("controller_loop_panicked: {panic}"),
));
}
}

Expand Down Expand Up @@ -117,9 +112,10 @@ impl Controller {
}
Some(Err(error)) => {
self.bus.publish(
Event::new(EventKind::ControllerRejected)
.with_task("controller")
.with_reason(format!("admission_waiter_failed: {error}")),
Event::runtime_failure(
"controller",
format!("admission_waiter_failed: {error}"),
),
);
}
None => {}
Expand All @@ -137,9 +133,10 @@ impl Controller {
}
Some(Err(error)) => {
self.bus.publish(
Event::new(EventKind::ControllerRejected)
.with_task("controller")
.with_reason(format!("completion_waiter_failed: {error}")),
Event::runtime_failure(
"controller",
format!("completion_waiter_failed: {error}"),
),
);
}
None => {}
Expand All @@ -157,9 +154,10 @@ impl Controller {
}
Some(Err(error)) => {
self.bus.publish(
Event::new(EventKind::ControllerRejected)
.with_task("controller")
.with_reason(format!("removal_waiter_failed: {error}")),
Event::runtime_failure(
"controller",
format!("removal_waiter_failed: {error}"),
),
);
}
None => {}
Expand All @@ -170,9 +168,10 @@ impl Controller {
Some(Ok(())) => {}
Some(Err(error)) => {
self.bus.publish(
Event::new(EventKind::ControllerRejected)
.with_task("controller")
.with_reason(format!("identity_operation_failed: {error}")),
Event::runtime_failure(
"controller",
format!("identity_operation_failed: {error}"),
),
);
}
None => {}
Expand Down Expand Up @@ -222,18 +221,17 @@ impl Controller {
Self::drain_workers(&mut identity_operations).await;
self.finalize_slot_state_on_shutdown().await;
if let Err(panic) = loop_result {
self.bus.publish(
Event::new(EventKind::ControllerRejected)
.with_task("controller")
.with_reason(format!("controller_loop_panicked: {panic}")),
);
self.bus.publish(Event::runtime_failure(
"controller",
format!("controller_loop_panicked: {panic}"),
));
}
Ok(())
}

/// Runs one controller work unit behind a panic boundary.
///
/// A panic is converted into a diagnostic `ControllerRejected` event and the loop continues.
/// A panic is converted into a diagnostic `RuntimeFailure` event and the loop continues.
///
/// This guard does not repair partially updated slot state by itself.
/// Callers that park watcher state must still make sure the watcher is resolved or returned on every failure path.
Expand All @@ -246,11 +244,10 @@ impl Controller {
match crate::core::panic_guard::guarded(fut).await {
Ok(output) => Some(output),
Err(msg) => {
self.bus.publish(
Event::new(EventKind::ControllerRejected)
.with_task("controller")
.with_reason(format!("{who}_panicked: {msg}")),
);
self.bus.publish(Event::runtime_failure(
"controller",
format!("{who}_panicked: {msg}"),
));
None
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/controller/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use tokio_util::sync::CancellationToken;

use crate::{
core::{OutcomeTx, SupervisorCore, TaskOutcome},
events::{Bus, Event, EventKind},
events::{Bus, Event, EventKind, RejectionKind},
identity::TaskId,
};

Expand Down Expand Up @@ -152,9 +152,10 @@ impl Controller {
/// Resolves a parked watched submission as `Rejected`.
///
/// This is a no-op for unwatched submissions and for watched submissions already handed to the runtime registry.
fn finalize_rejected(&self, id: TaskId, reason: &str) {
fn finalize_rejected(&self, id: TaskId, kind: RejectionKind, reason: &str) {
if let Some((_, tx)) = self.watchers.remove(&id) {
let _ = tx.send(TaskOutcome::Rejected {
kind,
reason: Arc::from(reason),
});
}
Expand Down Expand Up @@ -184,9 +185,14 @@ impl Controller {
self.bus.publish(
Event::new(EventKind::ControllerRejected)
.with_id(id)
.with_rejection_kind(RejectionKind::ControllerShuttingDown)
.with_reason(crate::reasons::CONTROLLER_SHUTTING_DOWN),
);
self.finalize_rejected(id, crate::reasons::CONTROLLER_SHUTTING_DOWN);
self.finalize_rejected(
id,
RejectionKind::ControllerShuttingDown,
crate::reasons::CONTROLLER_SHUTTING_DOWN,
);
}
}

Expand Down
12 changes: 9 additions & 3 deletions src/controller/core/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use tokio::sync::Mutex;

use crate::{
controller::slot::SlotState,
events::{Event, EventKind},
events::{Event, EventKind, RejectionKind},
identity::TaskId,
};

Expand Down Expand Up @@ -57,9 +57,10 @@ impl Controller {
Event::new(EventKind::ControllerRejected)
.with_task(slot_name)
.with_id(id)
.with_rejection_kind(RejectionKind::QueueFull)
.with_reason(reason.clone()),
);
self.finalize_rejected(id, &reason);
self.finalize_rejected(id, RejectionKind::QueueFull, &reason);
true
} else {
false
Expand All @@ -86,9 +87,14 @@ impl Controller {
Event::new(EventKind::ControllerRejected)
.with_task(Arc::clone(slot_name))
.with_id(displaced_id)
.with_rejection_kind(RejectionKind::SupersededByReplace)
.with_reason(crate::reasons::SUPERSEDED_BY_REPLACE),
);
self.finalize_rejected(displaced_id, crate::reasons::SUPERSEDED_BY_REPLACE);
self.finalize_rejected(
displaced_id,
RejectionKind::SupersededByReplace,
crate::reasons::SUPERSEDED_BY_REPLACE,
);
} else {
slot.queue.push_front((id, task_spec));
}
Expand Down
11 changes: 9 additions & 2 deletions src/controller/core/shutdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use tokio::{sync::mpsc, task::JoinSet};

use crate::RuntimeError;
use crate::core::TaskOutcome;
use crate::events::{Event, EventKind};
use crate::events::{Event, EventKind, RejectionKind};

use super::{Controller, ControllerCommand};

Expand All @@ -39,6 +39,7 @@ impl Controller {
ControllerCommand::Submit(sub) => {
let mut event = Event::new(EventKind::ControllerRejected)
.with_id(sub.id)
.with_rejection_kind(RejectionKind::ControllerShuttingDown)
.with_reason(crate::reasons::CONTROLLER_SHUTTING_DOWN);
if let Some(slot_name) = sub.spec.slot_override() {
event = event.with_task(slot_name.to_owned());
Expand All @@ -47,6 +48,7 @@ impl Controller {

if let Some(done) = sub.done {
let _ = done.send(TaskOutcome::Rejected {
kind: RejectionKind::ControllerShuttingDown,
reason: Arc::from(crate::reasons::CONTROLLER_SHUTTING_DOWN),
});
}
Expand Down Expand Up @@ -76,9 +78,14 @@ impl Controller {
Event::new(EventKind::ControllerRejected)
.with_task(Arc::clone(&slot_name))
.with_id(id)
.with_rejection_kind(RejectionKind::ControllerShuttingDown)
.with_reason(crate::reasons::CONTROLLER_SHUTTING_DOWN),
);
self.finalize_rejected(id, crate::reasons::CONTROLLER_SHUTTING_DOWN);
self.finalize_rejected(
id,
RejectionKind::ControllerShuttingDown,
crate::reasons::CONTROLLER_SHUTTING_DOWN,
);
}
}

Expand Down
11 changes: 5 additions & 6 deletions src/controller/core/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use tokio::{sync::Mutex, task::JoinHandle};

use crate::events::{Bus, Event, EventKind};
use crate::events::{Bus, Event};

pub(super) struct ControllerTask {
state: Mutex<ControllerTaskState>,
Expand Down Expand Up @@ -36,11 +36,10 @@ impl ControllerTask {
let clean = match handle.await {
Ok(()) => true,
Err(error) => {
bus.publish(
Event::new(EventKind::ControllerRejected)
.with_task("controller")
.with_reason(format!("controller_join_failed: {error}")),
);
bus.publish(Event::runtime_failure(
"controller",
format!("controller_join_failed: {error}"),
));
false
}
};
Expand Down
Loading
Loading