mirror of
https://github.com/ksyasuda/dotfiles.git
synced 2026-03-20 06:11:27 -07:00
update skills
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
# Gotchas & Best Practices
|
||||
|
||||
## Common Errors
|
||||
|
||||
### "setState() not syncing"
|
||||
|
||||
**Cause:** Mutating state directly or not calling `setState()` after modifications
|
||||
**Solution:** Always use `setState()` with immutable updates:
|
||||
```ts
|
||||
// ❌ this.state.count++
|
||||
// ✅ this.setState({...this.state, count: this.state.count + 1})
|
||||
```
|
||||
|
||||
### "Message history grows unbounded (AIChatAgent)"
|
||||
|
||||
**Cause:** `this.messages` in `AIChatAgent` accumulates all messages indefinitely
|
||||
**Solution:** Manually trim old messages periodically:
|
||||
```ts
|
||||
export class ChatAgent extends AIChatAgent<Env> {
|
||||
async onChatMessage(onFinish) {
|
||||
// Keep only last 50 messages
|
||||
if (this.messages.length > 50) {
|
||||
this.messages = this.messages.slice(-50);
|
||||
}
|
||||
|
||||
return this.streamText({ model: openai("gpt-4"), messages: this.messages, onFinish });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### "SQL injection vulnerability"
|
||||
|
||||
**Cause:** Direct string interpolation in SQL queries
|
||||
**Solution:** Use parameterized queries:
|
||||
```ts
|
||||
// ❌ this.sql`...WHERE id = '${userId}'`
|
||||
// ✅ this.sql`...WHERE id = ${userId}`
|
||||
```
|
||||
|
||||
### "WebSocket connection timeout"
|
||||
|
||||
**Cause:** Not calling `conn.accept()` in `onConnect`
|
||||
**Solution:** Always accept connections:
|
||||
```ts
|
||||
async onConnect(conn: Connection, ctx: ConnectionContext) { conn.accept(); conn.setState({userId: "123"}); }
|
||||
```
|
||||
|
||||
### "Schedule limit exceeded"
|
||||
|
||||
**Cause:** More than 1000 scheduled tasks per agent
|
||||
**Solution:** Clean up old schedules and limit creation rate:
|
||||
```ts
|
||||
async checkSchedules() { if ((await this.getSchedules()).length > 800) console.warn("Near limit!"); }
|
||||
```
|
||||
|
||||
### "AI Gateway unavailable"
|
||||
|
||||
**Cause:** AI service timeout or quota exceeded
|
||||
**Solution:** Add error handling and fallbacks:
|
||||
```ts
|
||||
try {
|
||||
return await this.env.AI.run(model, {prompt});
|
||||
} catch (e) {
|
||||
console.error("AI error:", e);
|
||||
return {error: "Unavailable"};
|
||||
}
|
||||
```
|
||||
|
||||
### "@callable method returns undefined"
|
||||
|
||||
**Cause:** Method doesn't return JSON-serializable value, or has non-serializable types
|
||||
**Solution:** Ensure return values are plain objects/arrays/primitives:
|
||||
```ts
|
||||
// ❌ Returns class instance
|
||||
@callable()
|
||||
async getData() { return new Date(); }
|
||||
|
||||
// ✅ Returns serializable object
|
||||
@callable()
|
||||
async getData() { return { timestamp: Date.now() }; }
|
||||
```
|
||||
|
||||
### "Resumable stream not resuming"
|
||||
|
||||
**Cause:** Stream ID must be deterministic for resumption to work
|
||||
**Solution:** Use AIChatAgent (automatic) or ensure consistent stream IDs:
|
||||
```ts
|
||||
// AIChatAgent handles this automatically
|
||||
export class ChatAgent extends AIChatAgent<Env> {
|
||||
// Resumption works out of the box
|
||||
}
|
||||
```
|
||||
|
||||
### "MCP connection loss on hibernation"
|
||||
|
||||
**Cause:** MCP server connections don't survive hibernation
|
||||
**Solution:** Re-register servers in `onStart()` or check connection status:
|
||||
```ts
|
||||
onStart() {
|
||||
// Re-register MCP servers after hibernation
|
||||
await this.mcp.registerServer("github", { url: env.MCP_URL, auth: {...} });
|
||||
}
|
||||
```
|
||||
|
||||
### "Agent not found"
|
||||
|
||||
**Cause:** Durable Object binding missing or incorrect class name
|
||||
**Solution:** Verify DO binding in wrangler.jsonc and class name matches
|
||||
|
||||
## Rate Limits & Quotas
|
||||
|
||||
| Resource/Limit | Value | Notes |
|
||||
|----------------|-------|-------|
|
||||
| CPU per request | 30s (std), 300s (max) | Set in wrangler.jsonc |
|
||||
| Memory per instance | 128MB | Shared with WebSockets |
|
||||
| Storage per agent | 10GB | SQLite storage |
|
||||
| Scheduled tasks | 1000 per agent | Monitor with `getSchedules()` |
|
||||
| WebSocket connections | Unlimited | Within memory limits |
|
||||
| SQL columns | 100 | Per table |
|
||||
| SQL row size | 2MB | Key + value |
|
||||
| WebSocket message | 32MiB | Max size |
|
||||
| DO requests/sec | ~1000 | Per unique DO instance; rate limit if needed |
|
||||
| AI Gateway (Workers AI) | Model-specific | Check dashboard for limits |
|
||||
| MCP requests | Depends on server | Implement retry/backoff |
|
||||
|
||||
## Best Practices
|
||||
|
||||
### State Management
|
||||
- Use immutable updates: `setState({...this.state, key: newValue})`
|
||||
- Trim unbounded arrays (messages, logs) periodically
|
||||
- Store large data in SQL, not state
|
||||
|
||||
### SQL Usage
|
||||
- Create tables in `onStart()`, not `onRequest()`
|
||||
- Use parameterized queries: `` sql`WHERE id = ${id}` `` (NOT `` sql`WHERE id = '${id}'` ``)
|
||||
- Index frequently queried columns
|
||||
|
||||
### Scheduling
|
||||
- Monitor schedule count: `await this.getSchedules()`
|
||||
- Cancel completed tasks to stay under 1000 limit
|
||||
- Use cron strings for recurring tasks
|
||||
|
||||
### WebSockets
|
||||
- Always call `conn.accept()` in `onConnect()`
|
||||
- Handle client disconnects gracefully
|
||||
- Broadcast to `this.connections` efficiently
|
||||
|
||||
### AI Integration
|
||||
- Use `AIChatAgent` for chat interfaces (auto-streaming, resumption)
|
||||
- Trim message history to avoid token limits
|
||||
- Handle AI errors with try/catch and fallbacks
|
||||
|
||||
### Production Deployment
|
||||
- **Rate limiting:** Implement request throttling for high-traffic agents (>1000 req/s)
|
||||
- **Monitoring:** Log critical errors, track schedule count, monitor storage usage
|
||||
- **Graceful degradation:** Handle AI service outages with fallbacks
|
||||
- **Message trimming:** Enforce max history length (e.g., 100 messages) in AIChatAgent
|
||||
- **MCP reliability:** Re-register servers on hibernation, implement retry logic
|
||||
Reference in New Issue
Block a user