You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Problem
Consumer breakdown can get stuck in "Calculating..." state forever when
the Web Worker hangs and never resolves/rejects its promise.
**Root cause:** No timeout on `tokenWorker.calculate()` means if the
worker hangs:
- Promise never settles
- Code never reaches catch/finally blocks
- `pendingCalcs` never cleaned up
- UI stuck showing "Calculating..." indefinitely
This was observed during development when errors occurred.
## Solution
Add a 10-second timeout using `Promise.race`:
```typescript
const timeoutPromise = new Promise<never>((_, reject) =>
setTimeout(() => reject(new Error("Calculation timeout")), 10_000)
);
const fullStats = await Promise.race([
this.tokenWorker.calculate(messages, model),
timeoutPromise,
]);
```
**Why 10 seconds?**
- Generous enough for large message histories
- Responsive - anything longer feels like a bug to users
- Treated as error → caches empty result → prevents retry spam
## Unchanged: Original Cancellation Logic
The existing cancellation handling is **preserved and correct**:
```typescript
catch (error) {
if (error.message === "Cancelled by newer request") {
return; // Don't cache, let lazy trigger retry
}
// Real errors: cache empty to prevent infinite retries
this.cache.set(workspaceId, { ..., isCalculating: false });
}
```
**Why this matters:**
- **Cancellations** (transient): Don't cache → Lazy trigger retries
naturally
- **Real errors** (permanent): Cache empty → Prevent retry spam
- Removing this distinction breaks the system
## Net Changes
- **Added**: 6 lines (timeout constant + Promise.race wrapper)
- **Removed**: 0 lines
- **Net**: +6 lines, 0 complexity increase
## Testing
- ✅ Fresh load with large history (timeout doesn't trigger prematurely)
- ✅ Rapid workspace switching (cancellations still work correctly)
- ✅ Simulated worker hang (timeout fires, UI exits calculating state)
_Generated with `cmux`_
0 commit comments