///|
/// ExecutionContext for background tasks
/// Similar to Cloudflare Workers ExecutionContext
///|
/// Background task that will run after response is sent
pub(all) struct BackgroundTask {
/// Task function to execute
task : async () -> Unit
/// Task name for debugging
name : String
}
///|
/// ExecutionContext manages background tasks
pub(all) struct ExecutionContext {
/// Pending background tasks
priv tasks : Array[BackgroundTask]
/// Whether the context is still accepting tasks
priv mut active : Bool
}
///|
/// Create a new ExecutionContext
pub fn ExecutionContext::new() -> ExecutionContext {
{ tasks: [], active: true }
}
///|
/// Schedule a background task to run after response is sent
/// Similar to Cloudflare's ctx.waitUntil()
pub fn ExecutionContext::wait_until(
self : ExecutionContext,
task : async () -> Unit,
name? : String = "background",
) -> Unit {
if self.active {
self.tasks.push({ task, name })
}
}
///|
/// Implement ExecCtx trait for ExecutionContext
pub impl ExecCtx for ExecutionContext with wait_until(self, task, name~) {
self.wait_until(task, name~)
}
///|
/// Get number of pending tasks
pub fn ExecutionContext::pending_count(self : ExecutionContext) -> Int {
self.tasks.length()
}
///|
/// Check if context is still active
pub fn ExecutionContext::is_active(self : ExecutionContext) -> Bool {
self.active
}
///|
/// Deactivate context (no more tasks can be added)
pub fn ExecutionContext::deactivate(self : ExecutionContext) -> Unit {
self.active = false
}
///|
/// Execute all pending background tasks
/// Called after response is sent
pub async fn ExecutionContext::run_tasks(self : ExecutionContext) -> Unit {
self.active = false
for bg_task in self.tasks {
(bg_task.task)() catch {
e => println("Background task '\{bg_task.name}' failed: \{e}")
}
}
}
///|
/// Get all pending tasks (for testing)
pub fn ExecutionContext::get_tasks(
self : ExecutionContext,
) -> Array[BackgroundTask] {
self.tasks
}