p2j: add Background Tasks tutorial — usage patterns, event loop, use cases, internals
swadhinbiswas committed 3 months ago
8dac5ad
1 parent 58d4770
commit 8dac5ad
1 file changed
+120 -0
Showing 1 changed file+120-0
▼docs_site/src/content/docs/tutorials/background-tasks.md
+120-0
| @@ -0,0 +1,120 @@ | ||
1 | +--- | |
2 | +title: Background Tasks | |
3 | +description: Execute tasks after sending the response using BackgroundTasks. | |
4 | +--- | |
5 | + | |
6 | +Background tasks let you run code after the HTTP response has been sent, without blocking the client. This is useful for operations like sending emails, processing uploads, or triggering webhooks. | |
7 | + | |
8 | +## Basic Usage | |
9 | + | |
10 | +```python | |
11 | +from justapi import JustAPIApp, BackgroundTasks | |
12 | + | |
13 | +app = JustAPIApp() | |
14 | + | |
15 | + | |
16 | +def write_log(message: str): | |
17 | + with open("requests.log", "a") as f: | |
18 | + f.write(f"{message}\n") | |
19 | + | |
20 | + | |
21 | +@app.post("/submit") | |
22 | +def submit(request, tasks: BackgroundTasks): | |
23 | + tasks.add_task(write_log, f"New submission at {request.path}") | |
24 | + return {"message": "Request accepted"} | |
25 | +``` | |
26 | + | |
27 | +The response is sent immediately, and `write_log` runs in the background. | |
28 | + | |
29 | +## Multiple Background Tasks | |
30 | + | |
31 | +```python | |
32 | +def send_email(to: str, subject: str): | |
33 | + ... | |
34 | + | |
35 | +def update_analytics(endpoint: str): | |
36 | + ... | |
37 | + | |
38 | +def notify_slack(channel: str, message: str): | |
39 | + ... | |
40 | + | |
41 | + | |
42 | +@app.post("/order") | |
43 | +def create_order(request, tasks: BackgroundTasks): | |
44 | + tasks.add_task(send_email, "[email protected]", "Order confirmed") | |
45 | + tasks.add_task(update_analytics, "/order") | |
46 | + tasks.add_task(notify_slack, "#orders", "New order placed") | |
47 | + return {"message": "Order created"} | |
48 | +``` | |
49 | + | |
50 | +## Tasks with Return Values | |
51 | + | |
52 | +Background tasks can't return values to the client (the response is already sent). Instead, store results in a database or queue: | |
53 | + | |
54 | +```python | |
55 | +def process_file_async(file_path: str, db): | |
56 | + try: | |
57 | + result = expensive_processing(file_path) | |
58 | + db.execute( | |
59 | + "UPDATE files SET status = 'done', result = $1 WHERE path = $2", | |
60 | + [result, file_path], | |
61 | + ) | |
62 | + except Exception as e: | |
63 | + db.execute( | |
64 | + "UPDATE files SET status = 'failed', error = $1 WHERE path = $2", | |
65 | + [str(e), file_path], | |
66 | + ) | |
67 | + | |
68 | + | |
69 | +@app.post("/upload") | |
70 | +def upload(request, tasks: BackgroundTasks): | |
71 | + data = request.json() | |
72 | + tasks.add_task(process_file_async, data["file_path"], app.db) | |
73 | + return {"message": "Processing started", "status_url": "/status/file_123"} | |
74 | +``` | |
75 | + | |
76 | +## Tasks and the Event Loop | |
77 | + | |
78 | +Background tasks run on the Tokio async runtime. They don't block the main request handler: | |
79 | + | |
80 | +```python | |
81 | +import asyncio | |
82 | +from justapi import BackgroundTasks | |
83 | + | |
84 | + | |
85 | +async def send_welcome_email(email: str): | |
86 | + await asyncio.sleep(1) # Simulate async email sending | |
87 | + print(f"Welcome email sent to {email}") | |
88 | + | |
89 | + | |
90 | +@app.post("/signup") | |
91 | +async def signup(request, tasks: BackgroundTasks): | |
92 | + tasks.add_task(send_welcome_email, "[email protected]") | |
93 | + return {"message": "Signed up successfully"} | |
94 | +``` | |
95 | + | |
96 | +## When to Use Background Tasks | |
97 | + | |
98 | +| Use Case | Example | | |
99 | +|---|---| | |
100 | +| Email notifications | Welcome emails, password resets | | |
101 | +| Webhook delivery | Notify external services | | |
102 | +| Log aggregation | Write access logs to external service | | |
103 | +| Analytics | Track page views, events | | |
104 | +| File processing | Resize images after upload | | |
105 | +| Cache warming | Rebuild cache after data change | | |
106 | +| Webhook triggers | Notify external systems | | |
107 | + | |
108 | +## How It Works Internally | |
109 | + | |
110 | +1. `BackgroundTasks.add_task()` registers a callable with arguments | |
111 | +2. The handler executes and returns the response immediately | |
112 | +3. After the response is sent, background tasks execute in order | |
113 | +4. Tasks run on the Tokio runtime with the GIL managed by PyO3 | |
114 | +5. If a task raises an exception, it's logged but doesn't affect the response | |
115 | + | |
116 | +## Next Steps | |
117 | + | |
118 | +- [Scheduler](/api-reference/scheduler/) — Cron-based periodic tasks | |
119 | +- [WebSockets & SSE](/tutorials/websockets-sse/) — Real-time client notifications | |
120 | +- [Streaming Output](/advanced/streaming-output/) — Stream task progress to clients | |
0 | 121 | |