use exfiltrate::provider::{Provider, ProviderResult, Row, SnapshotRequest};
use wasm_lite_std::time::Instant;
use crate::registry;
pub fn install() {
exfiltrate::provider::add_provider(ThreadPools);
}
struct ThreadPools;
impl Provider for ThreadPools {
fn subsystem(&self) -> &'static str {
"thread_pool"
}
fn description(&self) -> &'static str {
"executor thread pools: worker count, tasks in flight, and whether the pool is alive"
}
fn snapshot(&self, request: &SnapshotRequest<'_>) -> ProviderResult {
let Some(entries) = registry::entries() else {
return ProviderResult::Busy;
};
let stats = registry::stats();
let wanted: Option<u64> = match request.selector() {
Some(selector) => match selector.parse::<u64>() {
Ok(id) => Some(id),
Err(_) => {
return ProviderResult::Unavailable(format!(
"--id must be a pool id; got {selector:?}"
));
}
},
None => None,
};
let now = Instant::now();
let mut rows = Vec::new();
for entry in entries {
if request.should_stop() {
return ProviderResult::Partial(rows, "deadline".to_string());
}
if let Some(id) = wanted
&& entry.id != id
{
continue;
}
rows.push(
Row::new()
.support("id", entry.id)
.support("threads", entry.threads as u64)
.support("running_tasks", entry.running_tasks())
.support("alive", entry.alive)
.support(
"age_ms",
now.duration_since(entry.created).as_millis() as u64,
)
.local("name", entry.name.clone()),
);
}
if stats.dropped > 0 {
return ProviderResult::Partial(
rows,
format!(
"the registry has dropped {} pool(s) to stay within its capacity of {}; \
raise SOME_GLOBAL_EXECUTOR_REGISTRY_CAPACITY to keep more",
stats.dropped, stats.capacity
),
);
}
ProviderResult::Rows(rows)
}
}