wasm_framework/context.rs
1use crate::Response;
2use crate::Runnable;
3use service_logging::{LogEntry, LogQueue};
4use std::panic::UnwindSafe;
5
6/// Context manages the information flow for an incoming HTTP [`Request`],
7/// the application handler, and the generated HTTP [`Response`]. It holds a buffer
8/// for log messages, and a hook for deferred tasks to be processed after the [`Response`] is returned.
9#[derive(Default)]
10pub struct Context {
11 response: Response,
12 log_queue: LogQueue,
13 deferred: Vec<Box<dyn Runnable + UnwindSafe>>,
14 internal_error: Option<Box<dyn std::error::Error>>,
15}
16
17unsafe impl Send for Context {}
18
19impl Context {
20 /// Creates response builder
21 pub fn response(&mut self) -> &mut Response {
22 &mut self.response
23 }
24
25 /// Adds a task to the deferred task queue. The task queue uses
26 /// [event.waitUntil](https://developers.cloudflare.com/workers/runtime-apis/fetch-event)
27 /// to extend the lifetime of the request event, and runs tasks after the response
28 /// has been returned to the client.
29 /// Deferred tasks are often useful for logging and analytics.
30 pub fn defer(&mut self, task: Box<dyn Runnable + UnwindSafe>) {
31 self.deferred.push(task);
32 }
33
34 /// Returns pending log messages, emptying internal queue.
35 /// This is used for sending queued messages to an external log service
36 pub fn take_logs(&mut self) -> Vec<LogEntry> {
37 self.log_queue.take()
38 }
39
40 /// Returns deferred tasks, emptying internal list
41 pub(crate) fn take_tasks(&mut self) -> Vec<Box<dyn Runnable + UnwindSafe>> {
42 std::mem::take(&mut self.deferred)
43 }
44
45 /// Returns response, replacing self.response with default
46 pub(crate) fn take_response(&mut self) -> Response {
47 std::mem::take(&mut self.response)
48 }
49
50 /// Adds log to deferred queue
51 pub fn log(&mut self, e: LogEntry) {
52 self.log_queue.log(e);
53 }
54
55 /// Sets the internal error flag, which causes wasm_service to invoke the internal_error_handler
56 pub fn raise_internal_error(&mut self, e: Box<dyn std::error::Error>) {
57 self.internal_error = Some(e);
58 }
59
60 /// Returns whether the internal error flag has been set
61 pub fn is_internal_error(&self) -> Option<&dyn std::error::Error> {
62 self.internal_error.as_deref()
63 }
64}