Skip to content

Commit

Permalink
add more debug info
Browse files Browse the repository at this point in the history
  • Loading branch information
stepantubanov committed Oct 1, 2024
1 parent bfdb991 commit c64039d
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 39 deletions.
85 changes: 51 additions & 34 deletions src/enabled/controller.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, mem::replace, time::Duration};
use std::{collections::HashMap, fmt, mem::replace, time::Duration};

use tokio::{
sync::{mpsc, oneshot},
Expand All @@ -22,31 +22,58 @@ pub(crate) struct Controller {
events_rx: mpsc::UnboundedReceiver<(TaskId, TaskEvent)>,
}

#[derive(Debug)]
pub(crate) enum TaskState {
DidNotStart,
OutsideOperation,
WaitingForPermit {
NotStarted,
ExecutingOutsideOperation,
WaitingToStartOperation {
metadata: &'static OperationMetadata,
permit: oneshot::Sender<OperationPermit>,
locks: Vec<ParcheckLock>,
blocked_locks: Vec<ParcheckLock>,
},
InsideOperation {
ExecutingOperation {
metadata: &'static OperationMetadata,
},
Finished,
Invalid,
}

impl fmt::Display for OperationMetadata {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "'{}' (at {}:{})", self.name, self.file, self.line)
}
}

impl fmt::Debug for TaskState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NotStarted => f.write_str("not-started"),
Self::ExecutingOutsideOperation => f.write_str("executing-outside-parcheck-operation"),
Self::WaitingToStartOperation {
metadata,
locks,
blocked_locks,
..
} => {
write!(f, "waiting-to-start-operation {metadata} (locks: {locks:?}, blocked-locks: {blocked_locks:?})")
}
Self::ExecutingOperation { metadata } => {
write!(f, "executing-operation {metadata}")
}
Self::Finished => f.write_str("finished"),
Self::Invalid => f.write_str("invalid"),
}
}
}

impl TaskState {
pub(crate) fn can_execute(&self) -> bool {
self.executable_op().is_some()
}

pub(crate) fn executable_op(&self) -> Option<&'static OperationMetadata> {
match self {
Self::WaitingForPermit {
Self::WaitingToStartOperation {
metadata,
blocked_locks,
..
Expand All @@ -65,7 +92,7 @@ impl Controller {
.map(|(i, name)| {
(
Task::register(TaskId(i), name.clone(), events_tx.clone()),
TaskState::DidNotStart,
TaskState::NotStarted,
)
})
.collect();
Expand All @@ -85,11 +112,11 @@ impl Controller {
if this.tasks.iter().all(|(_, state)| {
matches!(
state,
TaskState::WaitingForPermit { .. } | TaskState::Finished
TaskState::WaitingToStartOperation { .. } | TaskState::Finished
)
}) {
for (task, state) in &mut this.tasks {
let TaskState::WaitingForPermit {
let TaskState::WaitingToStartOperation {
locks,
blocked_locks,
..
Expand All @@ -110,22 +137,12 @@ impl Controller {
match result {
Ok(()) => &self.tasks,
Err(Elapsed { .. }) => {
let tasks_in_progress: Vec<_> = self
let tasks = self
.tasks
.iter()
.filter_map(|(task, state)| match state {
TaskState::InsideOperation { metadata } => Some(format!(
"task '{}' in operation '{}' (at {}:{})",
task.name().0,
metadata.name,
metadata.file,
metadata.line
)),
_ => None,
})
.collect();

panic!("timed out, tasks in progress: {tasks_in_progress:?}");
.map(|(task, state)| format!("task '{}': {state:?}", task.name().0))
.collect::<Vec<_>>();
panic!("timed out, tasks: {tasks:?}");
}
}
}
Expand All @@ -134,7 +151,7 @@ impl Controller {
let (_, state) = &mut self.tasks[id.0];

let prev = replace(state, TaskState::Invalid);
let TaskState::WaitingForPermit {
let TaskState::WaitingToStartOperation {
metadata,
permit,
locks,
Expand All @@ -143,7 +160,7 @@ impl Controller {
else {
panic!("step_forward: task not waiting: {prev:?}");
};
*state = TaskState::InsideOperation { metadata };
*state = TaskState::ExecutingOperation { metadata };

assert!(
blocked_locks.is_empty(),
Expand All @@ -154,7 +171,7 @@ impl Controller {
// ignore error (channel closed)
let _ = permit.send(OperationPermit::Granted);

while matches!(self.tasks[id.0], (_, TaskState::InsideOperation { .. })) {
while matches!(self.tasks[id.0], (_, TaskState::ExecutingOperation { .. })) {
self.recv_event().await;
}

Expand All @@ -178,7 +195,7 @@ impl Controller {
.tasks
.iter()
.filter_map(|(task, state)| match state {
TaskState::InsideOperation { metadata } => Some(format!(
TaskState::ExecutingOperation { metadata } => Some(format!(
"task '{}' in operation '{}'",
task.name().0,
metadata.name
Expand All @@ -190,7 +207,7 @@ impl Controller {
.tasks
.iter()
.filter_map(|(task, state)| match state {
TaskState::WaitingForPermit {
TaskState::WaitingToStartOperation {
metadata,
blocked_locks,
..
Expand All @@ -211,34 +228,34 @@ impl Controller {
let (id, event) = self.events_rx.recv().await.expect("channel closed");
let (task, state) = &mut self.tasks[id.0];
*state = match event {
TaskEvent::TaskStarted => TaskState::OutsideOperation,
TaskEvent::TaskStarted => TaskState::ExecutingOutsideOperation,
TaskEvent::OperationPermitRequested {
metadata,
permit,
locks,
} => {
if let TaskState::InsideOperation { metadata: other } = state {
if let TaskState::ExecutingOperation { metadata: other } = state {
let _ = permit
.send(super::task::OperationPermit::OperationAlreadyInProgress { other });
return;
};

TaskState::WaitingForPermit {
TaskState::WaitingToStartOperation {
metadata,
permit,
blocked_locks: Vec::new(),
locks,
}
}
TaskEvent::OperationFinished => {
let TaskState::InsideOperation { .. } = state else {
let TaskState::ExecutingOperation { .. } = state else {
panic!(
"task '{}': received OperationFinished when not inside operation",
task.name().0
);
};

TaskState::OutsideOperation
TaskState::ExecutingOutsideOperation
}
TaskEvent::TaskFinished => {
let locks = self.locked_state.acquired_locks(id);
Expand Down
10 changes: 5 additions & 5 deletions src/enabled/schedule_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,14 @@ fn tasks_to_nodes(tasks: &[(Task, TaskState)]) -> impl Iterator<Item = Node> + '

fn task_state_to_node_state(task_state: &TaskState) -> NodeState {
match task_state {
TaskState::DidNotStart
| TaskState::OutsideOperation
| TaskState::InsideOperation { .. }
TaskState::NotStarted
| TaskState::ExecutingOutsideOperation
| TaskState::ExecutingOperation { .. }
| TaskState::Invalid => unreachable!(),
TaskState::WaitingForPermit { blocked_locks, .. } if blocked_locks.is_empty() => {
TaskState::WaitingToStartOperation { blocked_locks, .. } if blocked_locks.is_empty() => {
NodeState::Unvisited
}
TaskState::WaitingForPermit { .. } => NodeState::Unreachable {
TaskState::WaitingToStartOperation { .. } => NodeState::Unreachable {
reason: "blocked by locks",
},
TaskState::Finished => NodeState::Unreachable {
Expand Down

0 comments on commit c64039d

Please sign in to comment.