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
v0.11.0: handle very large tab counts (fixes #1)
Reported: with ~1600 tabs open, the export stalled and eventually crashed.
Reproduced against a real 1613-tab load. Four separate problems, only one of
which was the export.
1. The export made one Apple Event round-trip per property, per tab
(title/URL/loading inside the tab loop): ~4800 IPC calls at 1600 tabs.
Measured 53 ms/tab — 11.2 s at 213 tabs, ~85 s at 1613 (still running when
killed at 31 s). Now uses bulk access, `title of every tab of w`, which is
one round-trip per property per window. Cost scales with windows, not tabs.
Applied to both the Chromium and Safari scripts.
2. A timeout silently returned an empty list, so past roughly 380 tabs the app
reported "No open tabs found in the running browsers" — a failed read was
indistinguishable from having no tabs. Failures now raise ExportError, which
the existing dialog surfaces. Gather timeout 20 s -> 60 s; count timeout
5 s -> 20 s (a browser with 1600 tabs needs 3-4 s just to answer a bulk
count).
3. The counter was slower than its own poll timer, which is likely what the
report actually experienced. running_process_names() asked System Events for
the process list on every poll: 2248 ms measured. Combined with the count,
count_all() took 4.72 s against a 4 s timer. Now uses NSWorkspace, a local
API call needing no Automation permission: 44 ms. System Events kept as a
fallback when PyObjC isn't available.
4. No re-entrancy guard, so slow polls stacked up and piled concurrent
AppleScript calls on each other. refresh() now skips a tick if one is still
in flight; the next catches up.
Results at 1613 tabs:
export gather ~85 s (timed out, returned nothing) -> 2.0 s
full export failed -> 2.8 s
count_all() 4.72 s (vs a 4 s timer) -> 1.83 s
process lookup 2248 ms -> 44 ms
A hypothesis that proved wrong, recorded so nobody re-does it: AppleScript's
`outp & ...` string building was assumed to be quadratic. Benchmarked at 1600
concatenations in 0.08 s. The IPC round-trips were the whole story.
Tests: a forced timeout must raise rather than return empty, and the bulk
query's true/false booleans must still map to the yes/no the CSV uses.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>