Files
dbx/crates/dbx-core/src/query_cancel.rs
T
t8y2 cf4f25fd52 feat: extract dbx-core crate for web deployment support
Refactor all database drivers, query execution, schema operations, and
business logic into a shared `dbx-core` crate. The Tauri desktop app
becomes a thin shell delegating to dbx-core, enabling future web and
CLI frontends to reuse the same core.
2026-05-05 03:16:24 +08:00

99 lines
2.3 KiB
Rust

use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use tokio_util::sync::CancellationToken;
#[derive(Clone, Default)]
pub struct RunningQueries {
inner: Arc<Mutex<HashMap<String, CancellationToken>>>,
}
impl RunningQueries {
pub fn register(&self, execution_id: String) -> RegisteredQuery {
let token = CancellationToken::new();
self.inner
.lock()
.expect("running query registry poisoned")
.insert(execution_id.clone(), token.clone());
RegisteredQuery {
execution_id,
token,
running_queries: self.clone(),
}
}
pub fn cancel(&self, execution_id: &str) -> bool {
let token = self
.inner
.lock()
.expect("running query registry poisoned")
.get(execution_id)
.cloned();
if let Some(token) = token {
token.cancel();
true
} else {
false
}
}
#[cfg(test)]
pub fn has(&self, execution_id: &str) -> bool {
self.inner
.lock()
.expect("running query registry poisoned")
.contains_key(execution_id)
}
fn remove(&self, execution_id: &str) {
self.inner
.lock()
.expect("running query registry poisoned")
.remove(execution_id);
}
}
pub struct RegisteredQuery {
execution_id: String,
token: CancellationToken,
running_queries: RunningQueries,
}
impl RegisteredQuery {
pub fn token(&self) -> CancellationToken {
self.token.clone()
}
}
impl Drop for RegisteredQuery {
fn drop(&mut self) {
self.running_queries.remove(&self.execution_id);
}
}
#[cfg(test)]
mod tests {
use super::RunningQueries;
#[test]
fn cancel_marks_registered_query_as_cancelled() {
let running = RunningQueries::default();
let registered = running.register("exec-1".to_string());
assert!(running.cancel("exec-1"));
assert!(registered.token().is_cancelled());
}
#[test]
fn dropping_registration_removes_running_query() {
let running = RunningQueries::default();
let registered = running.register("exec-1".to_string());
assert!(running.has("exec-1"));
drop(registered);
assert!(!running.has("exec-1"));
}
}