Skip to content

refactor: replace AsyncRuntime with simpler CancellableTask#2136

Open
ZnqbuZ wants to merge 1 commit intoEasyTier:mainfrom
ZnqbuZ:utils/cancellable-task
Open

refactor: replace AsyncRuntime with simpler CancellableTask#2136
ZnqbuZ wants to merge 1 commit intoEasyTier:mainfrom
ZnqbuZ:utils/cancellable-task

Conversation

@ZnqbuZ
Copy link
Copy Markdown
Contributor

@ZnqbuZ ZnqbuZ commented Apr 19, 2026

@ZnqbuZ ZnqbuZ force-pushed the utils/cancellable-task branch 3 times, most recently from 33fe1cf to 2047878 Compare April 19, 2026 22:37
@ZnqbuZ ZnqbuZ marked this pull request as ready for review April 19, 2026 23:10
Copilot AI review requested due to automatic review settings April 19, 2026 23:10
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Refactors task management by replacing the previous AsyncRuntime state machine with a simpler CancellableTask built on CancellationToken + AbortOnDropHandle.

Changes:

  • Replace AsyncRuntime / AsyncRuntimeState implementation with CancellableTask abstraction.
  • Add convenience constructors (spawn, child, with_token) and implement Future for CancellableTask.
  • Enable tokio-util’s rt feature to use AbortOnDropHandle.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
easytier/src/utils/task.rs Replaces stateful runtime wrapper with a cancellable task handle based on AbortOnDropHandle and CancellationToken.
easytier/Cargo.toml Adds tokio-util rt feature required by AbortOnDropHandle.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread easytier/src/utils/task.rs Outdated
Comment thread easytier/src/utils/task.rs Outdated
Comment thread easytier/src/utils/task.rs Outdated
@ZnqbuZ ZnqbuZ force-pushed the utils/cancellable-task branch 2 times, most recently from 82595ee to ede5dd6 Compare April 20, 2026 08:22
@ZnqbuZ ZnqbuZ requested a review from Copilot April 20, 2026 08:23
add docstring for AsyncRuntime

task

task

clippy

ct

ct

ct
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Refactors the task utility away from a stateful AsyncRuntime into a simpler, one-shot CancellableTask backed by tokio_util::task::AbortOnDropHandle, enabling cancellation via CancellationToken and optional stop timeouts.

Changes:

  • Replace AsyncRuntime state machine with CancellableTask that is Future-aware and holds an abort-on-drop join handle.
  • Add stop(timeout) that cancels the token and optionally times out while awaiting completion.
  • Enable tokio-util’s rt feature to use tokio_util::task utilities.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
easytier/src/utils/task.rs Replaces AsyncRuntime with CancellableTask, adds spawn/child helpers and stop-with-timeout behavior.
easytier/Cargo.toml Enables tokio-util rt feature required for AbortOnDropHandle.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

})?,
None => self.handle.await,
}
.map_err(Into::into)
Comment on lines +16 to 21
impl<Output> Future for CancellableTask<Output> {
type Output = <AbortOnDropHandle<Output> as Future>::Output;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.handle).poll(cx)
}
}
tracing::warn!("task stop timeout after {:?}, aborted", timeout);
task.await
};
pub async fn stop(mut self, timeout: Option<Duration>) -> io::Result<Output> {
Comment on lines +28 to 37
pub fn with_spawner<S, F>(spawner: S, token: CancellationToken, future: F) -> Self
where
F: FnOnce(CancellationToken) -> Fut,
Fut: Future<Output = R> + Send + 'static,
S: FnOnce(F) -> JoinHandle<Output>,
F: Future<Output = Output>,
{
let mut state = self.state.lock();
if !matches!(*state, AsyncRuntimeState::Idle) {
return Err(anyhow::anyhow!("task is already running/stopping"));
}

let token = token.unwrap_or_default();

let task = {
let f = factory(token.clone());
let this = (*self).clone();
tokio::spawn(async move {
let result = f.await;
let mut state = this.state.lock();
if let AsyncRuntimeState::Running { id, .. } = &*state
&& *id == tokio::task::id()
{
take(&mut *state);
}
result
})
};

*state = AsyncRuntimeState::Running {
id: task.id(),
task: task.into(),
Self {
handle: AbortOnDropHandle::new(spawner(future)),
token,
};

Ok(())
}
}
F: Future<Output = Output> + Send + 'static,
{
let token = self.token.clone();
Self::new(token.clone(), factory(token))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants