refactor: replace AsyncRuntime with simpler CancellableTask#2136
refactor: replace AsyncRuntime with simpler CancellableTask#2136ZnqbuZ wants to merge 1 commit intoEasyTier:mainfrom
Conversation
ZnqbuZ
commented
Apr 19, 2026
- part of feat: customizable magic DNS #1862
33fe1cf to
2047878
Compare
There was a problem hiding this comment.
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/AsyncRuntimeStateimplementation withCancellableTaskabstraction. - Add convenience constructors (
spawn,child,with_token) and implementFutureforCancellableTask. - Enable
tokio-util’srtfeature to useAbortOnDropHandle.
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.
82595ee to
ede5dd6
Compare
add docstring for AsyncRuntime task task clippy ct ct ct
ede5dd6 to
fee8a7f
Compare
There was a problem hiding this comment.
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
AsyncRuntimestate machine withCancellableTaskthat isFuture-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’srtfeature to usetokio_util::taskutilities.
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) |
| 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> { |
| 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)) |