Смена аренды прокси больше не убивает живой браузер: инстанс паркуется под
своей арендой и достаётся тёплым, когда эта аренда возвращается. Прокси у
camoufox задаётся на launch (geoip=True вяжет фингерпринт к IP аренды), сменить
его у живого браузера нельзя — поэтому пул, а не per-context proxy.
Замер прода за 25 ч (06-07.09, docker logs tradein-browser) НЕ подтвердил
гипотезу «relaunch перед каждым fetch»: 154 launch'а на ~2000 cian-фетчей,
из них 104 — recycle-порог (то есть порог срабатывает), 49 — смена аренды.
В час пиковой чехарды аренд (07.09 00:xx, 24 relaunch'а на 25 фетчей) доля
отказов была 1/26 = 3.8% — НИЖЕ суточной 4.8%. Первым фетчем на свежем
инстансе падают 19 ошибок из 99 (12.3% против 4.2% на прогретом), остальные
80 размазаны по 86 разным URL и всем часам — это тяжёлый хвост латентности
Циана, отдельная задача.
Что замер подтвердил: инстансов никто не считал. Инстанс поднимался лениво на
поставщика и не закрывался никогда, поэтому пять поставщиков давали пять вечных
camoufox (~425 МиБ каждый) в контейнере с mem_limit 2560m. Cgroup за те же 25 ч:
memory.events max=40781, oom_kill=111, sock_throttled=22177. Поэтому пул идёт
вместе с потолком BROWSER_MAX_INSTANCES (default 4) и LRU-закрытием: пиковое
число браузеров теперь МЕНЬШЕ прежнего, а не больше.
Гонок не добавляет: снятие/установка инстанса синхронны (нет await между
dict-операциями), жертву берём только среди припаркованных и активных
инстансов со свободным _locks[provider] — занятый лок значит «страница
in-flight». Новых локов нет.
Попутно: BROWSER_CONCURRENCY внесена в _RETIRED_ENV — её задаёт compose, её
цитируют оба обоснования потолка памяти, а код её не читает; параллелизм
задаёт _locks[provider] (≤1 страница на поставщика, но поставщиков пять).