-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackground.mbt
More file actions
61 lines (55 loc) · 2.02 KB
/
Copy pathbackground.mbt
File metadata and controls
61 lines (55 loc) · 2.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Background tasks (← FastAPI's `BackgroundTasks`). A handler schedules work to
// run *after* its response has been sent to the client: the request path stays
// fast, and the deferred work (sending a mail, writing an audit log) happens on
// the way out. FastAPI injects a `BackgroundTasks` parameter; the explicit
// MoonBit equivalent is a request-scoped value the app hands a background-aware
// handler, whose queued thunks the app drains once the response is on the wire.
///|
/// A queue of deferred thunks (← FastAPI's `BackgroundTasks`). A background-aware
/// route receives one per request, calls `add_task` to enqueue work, and the app
/// runs the queue — in enqueue order — after the response has been sent.
pub struct BackgroundTasks {
tasks : Array[() -> Unit]
}
///|
/// An empty task queue.
pub fn BackgroundTasks::new() -> BackgroundTasks {
{ tasks: [], }
}
///|
/// Enqueue a thunk to run after the response is sent. Tasks run in the order they
/// were added, each after the previous returns (← `BackgroundTasks.add_task`).
pub fn BackgroundTasks::add_task(
self : BackgroundTasks,
task : () -> Unit,
) -> Unit {
self.tasks.push(task)
}
///|
/// How many tasks are queued — the app checks this to skip the drain when a route
/// scheduled nothing.
pub fn BackgroundTasks::len(self : BackgroundTasks) -> Int {
self.tasks.length()
}
///|
/// Run every queued task in order, then clear the queue. Called by the app once
/// the response has been handed to the transport, so a task's latency never
/// delays the client. Idempotent: a second call runs nothing.
pub fn BackgroundTasks::run(self : BackgroundTasks) -> Unit {
for task in self.tasks {
task()
}
self.tasks.clear()
}
///|
/// Move `other`'s queued tasks onto this queue (used when a mounted sub-app's
/// tasks bubble up to the request that reached it), leaving `other` empty.
fn BackgroundTasks::absorb(
self : BackgroundTasks,
other : BackgroundTasks,
) -> Unit {
for task in other.tasks {
self.tasks.push(task)
}
other.tasks.clear()
}