mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-12 12:13:51 +00:00
Lightpanda requires one CDP connection per tab (vs Chrome's shared-WS model). Add a Backend selector in pkg/browser/, branched lifecycle, and per-tab connection tracking via pageConns. - Backend type (chrome | lightpanda), WithBackend option, Backend() accessor. Auto-detected from /json/version when unset. - Lightpanda OpenTab mints a fresh conn, calls Target.createBrowserContext (required per-conn) + createTarget. - ListTabs / getPage are local-map only on Lightpanda (no /json/list, no auto-reconnect). - Shared closeManagedPageLocked helper used by CloseTab, evict, and the idle-page reaper. - Screenshot tool action errors out on Lightpanda (returns a placeholder image upstream; route the agent to snapshot instead).
46 lines
938 B
Go
46 lines
938 B
Go
package browser
|
|
|
|
import "time"
|
|
|
|
// runReaper periodically closes pages that have been idle longer than idleTimeout.
|
|
// Runs as a goroutine; exits when stopReaper is closed.
|
|
func (m *Manager) runReaper() {
|
|
ticker := time.NewTicker(60 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-m.stopReaper:
|
|
return
|
|
case <-ticker.C:
|
|
m.reapIdlePages()
|
|
}
|
|
}
|
|
}
|
|
|
|
// reapIdlePages closes pages idle longer than idleTimeout.
|
|
func (m *Manager) reapIdlePages() {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
if !m.isRunningLocked() {
|
|
return
|
|
}
|
|
|
|
now := time.Now()
|
|
for targetID, lastUsed := range m.pageLastUsed {
|
|
if now.Sub(lastUsed) <= m.idleTimeout {
|
|
continue
|
|
}
|
|
|
|
if _, ok := m.pages[targetID]; !ok {
|
|
delete(m.pageLastUsed, targetID)
|
|
continue
|
|
}
|
|
|
|
idleFor := now.Sub(lastUsed).Round(time.Second)
|
|
m.closeManagedPageLocked(targetID)
|
|
m.logger.Info("reaper: closed idle page", "targetId", targetID, "idle", idleFor)
|
|
}
|
|
}
|