feat(browser): add timeout, idle auto-close, and max-pages safety mechanisms

Prevent resource leaks and hanging actions in the browser tool:
- Per-action context timeout (default 30s, configurable via timeoutMs param or config)
- Idle page reaper goroutine closes pages unused for 10min (configurable)
- Max pages per tenant (default 5) with LRU eviction
- RefStore cleanup on page close/evict/reap to prevent memory leaks
This commit is contained in:
viettranx committed 2026-03-25 13:55:33 +07:00
1 parent afbecd3e4c
commit ee4d34ae28
8 files changed
+226 -12

No files matched your search

+7
View File
@@ -22,6 +22,7 @@ func (m *Manager) reconnectLocked() error {
m.pages = make(map[string]*rod.Page)
m.console = make(map[string][]ConsoleMessage)
m.pageTenants = make(map[string]string)
m.pageLastUsed = make(map[string]time.Time)
m.refs = NewRefStore()
controlURL, err := resolveRemoteCDP(m.remoteURL)
@@ -100,6 +101,11 @@ func (m *Manager) getPageForTenant(targetID, tenantID string) (*rod.Page, error)
}
// If no tenant context or master tenant, allow access to all pages
if tenantID == "" || tenantID == MasterTenantID {
resolvedTID := targetID
if targetID == "" {
resolvedTID = string(page.TargetID)
}
m.touchPageLocked(resolvedTID)
return page, nil
}
// Check ownership: page must belong to this tenant
@@ -110,6 +116,7 @@ func (m *Manager) getPageForTenant(targetID, tenantID string) (*rod.Page, error)
if owner, ok := m.pageTenants[resolvedTID]; ok && owner != tenantID {
return nil, fmt.Errorf("tab not found: %s", targetID)
}
m.touchPageLocked(resolvedTID)
return page, nil
}