p4f-i: add Agent System, Streaming Output, Performance Tuning, Resilience advanced guides

swadhinbiswas committed 3 months ago
578b09d
1 parent a0a4f2a
commit 578b09d
4 files changed
+493 -0
▼docs_site/src/content/docs/advanced/agent-system.md
+123-0
1
+---
2
+title: Agent System (MCP Tools & Sessions)
3
+description: Build AI agents with native MCP tools, durable session state, and validated streaming.
4
+---
5
+
6
+JustAPI includes a first-class agent-native system that differentiates it from traditional web frameworks. It provides **MCP tools**, **durable sessions**, and **validated streaming** — all owned by Rust.
7
+
8
+## MCP Tools (`@app.tool`)
9
+
10
+Register Python functions as MCP-compatible tools. Schemas are inferred from type hints:
11
+
12
+```python
13
+from justapi import JustAPIApp
14
+
15
+app = JustAPIApp()
16
+
17
+
18
+@app.tool
19
+def add(a: int, b: int) -> int:
20
+ """Add two integers."""
21
+ return a + b
22
+
23
+
24
+@app.tool
25
+def search_docs(query: str, top_k: int = 3) -> list:
26
+ """Search documentation."""
27
+ return [{"text": "JustAPI runs routing in Rust", "score": 0.95}]
28
+```
29
+
30
+### Tool Discovery & Invocation
31
+
32
+Tools are automatically exposed via system routes:
33
+
34
+```bash
35
+# List all registered tools
36
+GET /_system/tools
37
+
38
+# Call a tool
39
+POST /_system/tools/call
40
+Content-Type: application/json
41
+
42
+{"name": "add", "arguments": {"a": 5, "b": 7}}
43
+```
44
+
45
+### MCP Stdio Server
46
+
47
+```python
48
+app.run_mcp_stdio() # Run an MCP stdio server for local AI tool use
49
+```
50
+
51
+## Durable Sessions (`app.enable_sessions()`)
52
+
53
+Rust-backed per-client state storage:
54
+
55
+```python
56
+app.enable_sessions()
57
+
58
+
59
+@app.get("/agent/state")
60
+def agent_state(request, session: Session):
61
+ prior = session.get().get("runs", 0)
62
+ session.update(runs=prior + 1)
63
+ return {"session_id": session.id, "runs": prior + 1}
64
+```
65
+
66
+Sessions are identified by the `justapi_session` cookie or `?session=` query parameter.
67
+
68
+## Validated Streaming (`@app.stream_json`)
69
+
70
+Stream generator output as NDJSON or JSON array, validating every item in Rust:
71
+
72
+```python
73
+STEP_SCHEMA = {
74
+ "type": "object",
75
+ "properties": {
76
+ "step": {"type": "string"},
77
+ "result": {},
78
+ },
79
+ "required": ["step", "result"],
80
+}
81
+
82
+
83
+@app.stream_json("/agent/run", schema=STEP_SCHEMA, mode="ndjson")
84
+def agent_run(request, session: Session):
85
+ yield {"step": "think", "result": "Analyzing..."}
86
+ yield {"step": "act", "result": "Performing task..."}
87
+ yield {"step": "observe", "result": "Task complete"}
88
+```
89
+
90
+Invalid items abort the stream — clients never see partial or invalid data.
91
+
92
+## Complete Example
93
+
94
+```python
95
+from justapi import JustAPIApp, Session
96
+
97
+app = JustAPIApp()
98
+app.enable_sessions()
99
+app.enable_system_routes()
100
+
101
+
102
+@app.tool
103
+def add(a: int, b: int) -> int:
104
+ return a + b
105
+
106
+
107
+@app.stream_json("/run", schema=STEP_SCHEMA, mode="ndjson")
108
+def run(request, session: Session):
109
+ result = add(2, 3)
110
+ prior = session.get().get("runs", 0)
111
+ session.update(runs=prior + 1)
112
+ yield {"step": "compute", "result": result}
113
+
114
+
115
+if __name__ == "__main__":
116
+ app.run("127.0.0.1:8000")
117
+```
118
+
119
+## See Also
120
+
121
+- [Session API](/api-reference/session/) — Session reference
122
+- [Streaming Output](/advanced/streaming-output/) — Validated streaming deep dive
123
+- [Dependency Injection API](/api-reference/dependency-injection/) — Session in DI
0
124
▼docs_site/src/content/docs/advanced/performance-tuning.md
+132-0
1
+---
2
+title: Performance Tuning
3
+description: Optimize your JustAPI application for maximum throughput and minimum latency.
4
+---
5
+
6
+## Worker Configuration
7
+
8
+### Multi-Worker Mode
9
+
10
+```bash
11
+justapi serve --host 0.0.0.0 --port 8080 --workers 4
12
+```
13
+
14
+Each worker is a separate OS process. Workers share no state — use Redis/Postgres for shared data.
15
+
16
+### Auto-Scaling Workers
17
+
18
+```bash
19
+justapi serve --scale --min-workers 2 --max-workers 8 \
20
+ --scale-high 1000 --scale-cooldown 30
21
+```
22
+
23
+| Flag | Default | Description |
24
+|---|---|---|
25
+| `--workers` | CPU count | Fixed number of workers |
26
+| `--scale` | off | Enable load-based auto-scaling |
27
+| `--min-workers` | 2 | Minimum workers |
28
+| `--max-workers` | CPU count | Maximum workers |
29
+| `--scale-low` | 100 | RPS threshold to scale down |
30
+| `--scale-high` | 1000 | RPS threshold to scale up |
31
+| `--scale-cooldown` | 30 | Seconds between scaling events |
32
+
33
+## Connection Pool Tuning
34
+
35
+```python
36
+app.set_database(
37
+ "postgres://localhost/mydb",
38
+ max_connections=20, # Pool size
39
+ request_acquire_timeout=1.0, # Timeout for pool saturation
40
+)
41
+```
42
+
43
+- Match pool size to expected concurrency
44
+- Set `request_acquire_timeout` low (1-3s) for fast failure under load
45
+- Use connection pooling behind the app for higher concurrency
46
+
47
+## Body Size Limits
48
+
49
+```python
50
+app.run("0.0.0.0:8000", max_body_size=1024 * 1024) # 1 MiB
51
+```
52
+
53
+Tight limits prevent memory exhaustion under load. Default is 50 MiB.
54
+
55
+## Request Timeouts
56
+
57
+Set timeouts to bound worst-case latency:
58
+
59
+```bash
60
+justapi serve --timeout 30 # 30 second request timeout
61
+```
62
+
63
+Requests exceeding the timeout return **504 Gateway Timeout**.
64
+
65
+## TLS Overhead
66
+
67
+TLS adds approximately **10.7%** overhead vs. plain HTTP. For maximum performance:
68
+
69
+1. Terminate TLS at the edge proxy (nginx, Caddy, cloud LB)
70
+2. Run JustAPI on a private loopback or Unix socket
71
+3. Pass `X-Forwarded-For` and `X-Forwarded-Proto` from the proxy
72
+
73
+## Compression Trade-offs
74
+
75
+| Algorithm | Compression Ratio | Speed |
76
+|---|---|---|
77
+| None | 1.0x | Fastest |
78
+| gzip (level 1) | ~3x | Fast |
79
+| gzip (level 9) | ~5x | Slow |
80
+| brotli | ~4x | Medium |
81
+| zstd | ~5x | Fast |
82
+
83
+Enable compression only when bandwidth is the bottleneck:
84
+
85
+```rust
86
+// In Cargo.toml features
87
+justapi-core = { features = ["compression"] }
88
+```
89
+
90
+## Route-Lookup Cache
91
+
92
+JustAPI automatically caches route lookups for high-traffic paths. No configuration needed — the cache is always active.
93
+
94
+## Native Fast Path
95
+
96
+Maximum throughput comes from the native fast path:
97
+
98
+```python
99
+@app.post("/fast", body_schema=Schema, native=True)
100
+def fast_handler(request):
101
+ return {"status": "ok"} # 724k+ RPS
102
+```
103
+
104
+See [Native Fast Path](/advanced/native-fast-path/) for details.
105
+
106
+## K8s Overhead
107
+
108
+When running in Kubernetes, expect approximately **8.4%** throughput degradation due to networking overhead. Mitigate by:
109
+
110
+1. Using host networking mode
111
+2. Setting resource requests/limits appropriately
112
+3. Tuning kube-proxy to use `iptables` mode
113
+
114
+## Benchmark Methodology
115
+
116
+```bash
117
+# Warm up: 5 seconds
118
+oha -z 5s http://localhost:8080/hello
119
+
120
+# Benchmark: 30 seconds, 100 concurrent connections
121
+oha -z 30s -c 100 http://localhost:8080/hello
122
+
123
+# Results: p50, p95, p99 latency, RPS, peak RSS
124
+```
125
+
126
+Run minimum 3 runs per workload to establish distribution.
127
+
128
+## See Also
129
+
130
+- [Native Fast Path](/advanced/native-fast-path/) — 724k+ RPS execution
131
+- [Production Checklist](/deployment/production-checklist/) — Production deployment settings
132
+- [Benchmarking Guide](/contributing/benchmarking-guide/) — Adding benchmarks
0
133
▼docs_site/src/content/docs/advanced/resilience-patterns.md
+123-0
1
+---
2
+title: Resilience Patterns
3
+description: Protect your application with circuit breakers, rate limiting, bulkheads, and graceful degradation.
4
+---
5
+
6
+JustAPI incorporates enterprise resilience primitives directly in the Rust engine.
7
+
8
+## Circuit Breakers
9
+
10
+Automatically stop calling a failing service when errors exceed a threshold:
11
+
12
+```python
13
+app.enable_circuit_breaker(
14
+ failure_threshold=5, # Open after 5 consecutive failures
15
+ reset_timeout_ms=30000, # Try again after 30 seconds
16
+)
17
+```
18
+
19
+States:
20
+- **Closed** — Normal operation, requests pass through
21
+- **Open** — Requests fail fast with 503
22
+- **Half-Open** — Probe request allowed; success → Closed, failure → Open
23
+
24
+## Request Coalescing
25
+
26
+Deduplicate concurrent identical requests so only one hits the backend:
27
+
28
+```python
29
+app.enable_request_coalescing(
30
+ headers=["accept"], # Consider these headers for dedup keys
31
+)
32
+```
33
+
34
+When 100 identical requests arrive simultaneously:
35
+- Only 1 request reaches the handler
36
+- The response is shared across all 100 callers
37
+- Saves backend resources on cacheable/read-only endpoints
38
+
39
+## Rate Limiting
40
+
41
+### Global Rate Limiter
42
+
43
+```python
44
+app.enable_rate_limiter(max_requests=1000, window_seconds=60)
45
+```
46
+
47
+### Per-IP Rate Limiter
48
+
49
+```python
50
+app.enable_ip_rate_limiter(max_requests=100, window_seconds=60)
51
+```
52
+
53
+Exceeding limits returns **429 Too Many Requests** with `Retry-After` header.
54
+
55
+## Bulkhead Pattern
56
+
57
+Limit concurrent requests to prevent resource exhaustion:
58
+
59
+```python
60
+app.enable_bulkhead(max_concurrent=100)
61
+```
62
+
63
+When the limit is exceeded, requests receive **503 Service Unavailable**.
64
+
65
+## Timeout Middleware
66
+
67
+Cancel requests that exceed the time limit:
68
+
69
+```python
70
+app.enable_timeout(seconds=30)
71
+```
72
+
73
+Returns **504 Gateway Timeout** when exceeded.
74
+
75
+## Graceful Degradation
76
+
77
+```python
78
+app.enable_fallback_middleware(
79
+ fallback_response={"status": "degraded", "message": "Please try again later"},
80
+)
81
+```
82
+
83
+## Graceful Shutdown
84
+
85
+JustAPI handles SIGINT/SIGTERM automatically:
86
+
87
+1. Stop accepting new connections
88
+2. Drain in-flight requests (with configurable timeout)
89
+3. Call plugin `on_shutdown()` hooks
90
+4. Close database connections
91
+5. Exit cleanly
92
+
93
+## Panic Model
94
+
95
+In production, Rust panics **abort the process** (not unwind). The supervisor (Docker, systemd, K8s) restarts the process immediately:
96
+
97
+```toml
98
+# Cargo.toml
99
+[profile.release]
100
+panic = "abort"
101
+```
102
+
103
+This avoids undefined behavior across the PyO3 FFI boundary during panics.
104
+
105
+## Configuration Summary
106
+
107
+```python
108
+app = JustAPIApp()
109
+
110
+# Resilience
111
+app.enable_circuit_breaker(failure_threshold=5, reset_timeout_ms=30000)
112
+app.enable_request_coalescing(headers=["accept"])
113
+app.enable_rate_limiter(max_requests=1000, window_seconds=60)
114
+app.enable_ip_rate_limiter(max_requests=100, window_seconds=60)
115
+app.enable_bulkhead(max_concurrent=100)
116
+app.enable_timeout(seconds=30)
117
+```
118
+
119
+## See Also
120
+
121
+- [Production Checklist](/deployment/production-checklist/) — Production deployment
122
+- [Security](/security/policy/) — Security policy and OWASP compliance
123
+- [Observability](/observability/metrics-monitoring/) — Monitoring resilience signals
0
124
▼docs_site/src/content/docs/advanced/streaming-output.md
+115-0
1
+---
2
+title: Streaming Output
3
+description: Stream responses with Rust-side validation using @app.stream_json and StreamingResponse.
4
+---
5
+
6
+JustAPI supports two streaming approaches: the validated `@app.stream_json` and the flexible `StreamingResponse`.
7
+
8
+## `@app.stream_json` (Validated Streaming)
9
+
10
+Every yielded item is validated against a JSON Schema **in Rust** before being written to the socket. Invalid items abort the stream.
11
+
12
+### NDJSON Mode
13
+
14
+```python
15
+from justapi import JustAPIApp
16
+
17
+app = JustAPIApp()
18
+
19
+SCHEMA = {
20
+ "type": "object",
21
+ "properties": {
22
+ "step": {"type": "string"},
23
+ "value": {"type": "number"},
24
+ },
25
+ "required": ["step", "value"],
26
+}
27
+
28
+
29
+@app.stream_json("/stream", schema=SCHEMA, mode="ndjson")
30
+def stream(request):
31
+ for i in range(10):
32
+ yield {"step": f"item-{i}", "value": i}
33
+```
34
+
35
+Output:
36
+
37
+```
38
+{"step":"item-0","value":0}
39
+{"step":"item-1","value":1}
40
+...
41
+```
42
+
43
+### Array Mode
44
+
45
+```python
46
+@app.stream_json("/array", schema=SCHEMA, mode="array")
47
+def stream_array(request):
48
+ for i in range(10):
49
+ yield {"step": f"item-{i}", "value": i}
50
+```
51
+
52
+Output:
53
+
54
+```json
55
+[{"step":"item-0","value":0},{"step":"item-1","value":1},...]
56
+```
57
+
58
+### Validation
59
+
60
+If an item doesn't match the schema, the stream is **aborted immediately** and the client receives an error. This guarantees clients never see partial or invalid data.
61
+
62
+## `StreamingResponse` (Flexible Streaming)
63
+
64
+For custom streaming needs:
65
+
66
+```python
67
+import asyncio
68
+from justapi.responses import StreamingResponse
69
+
70
+
71
+@app.get("/events")
72
+async def events(request):
73
+ async def generate():
74
+ for i in range(10):
75
+ yield f"data: Event #{i}\n\n"
76
+ await asyncio.sleep(1)
77
+
78
+ return StreamingResponse(generate(), media_type="text/event-stream")
79
+```
80
+
81
+## SSE (Server-Sent Events)
82
+
83
+The `text/event-stream` content type enables browser EventSource API:
84
+
85
+```javascript
86
+const source = new EventSource("/events");
87
+source.onmessage = (event) => console.log(event.data);
88
+```
89
+
90
+## Large File Streaming
91
+
92
+```python
93
+import aiofiles
94
+from justapi.responses import StreamingResponse
95
+
96
+
97
+@app.get("/large-file")
98
+async def download(request):
99
+ async def file_chunks():
100
+ async with aiofiles.open("data.csv", "rb") as f:
101
+ while chunk := await f.read(65536):
102
+ yield chunk
103
+
104
+ return StreamingResponse(file_chunks(), media_type="text/csv")
105
+```
106
+
107
+## Performance
108
+
109
+Streaming responses use Rust's `StreamBody` with zero-copy chunks. Overhead is minimal — measured at <0.05 ms per chunk.
110
+
111
+## See Also
112
+
113
+- [Agent System](/advanced/agent-system/) — Streaming with sessions and tools
114
+- [WebSockets & SSE Tutorial](/tutorials/websockets-sse/) — Real-time communication
115
+- [Response Classes API](/api-reference/responses/) — Response reference
0
116