feat: add container manager CLI commands and docker-compose overlay for admin container lifecycle

This commit is contained in:
2026-06-09 04:41:27 +00:00
parent 317126efc2
commit c565e3b55c
83 changed files with 6078 additions and 84 deletions
+7 -7
View File
@@ -33,10 +33,14 @@ class BotBrowser:
self._page = await self._context.new_page()
async def close(self) -> None:
context, self._context = self._context, None
browser, self._browser = self._browser, None
playwright, self._playwright = self._playwright, None
self._page = None
for label, resource, shutdown in (
("context", self._context, lambda r: r.close()),
("browser", self._browser, lambda r: r.close()),
("playwright", self._playwright, lambda r: r.stop()),
("context", context, lambda r: r.close()),
("browser", browser, lambda r: r.close()),
("playwright", playwright, lambda r: r.stop()),
):
if resource is None:
continue
@@ -44,10 +48,6 @@ class BotBrowser:
await shutdown(resource)
except Exception as e:
logger.debug("Browser %s close error: %s", label, e)
self._page = None
self._context = None
self._browser = None
self._playwright = None
@property
def page(self) -> Page:
+15 -2
View File
@@ -135,8 +135,9 @@ class BotsService(BaseService):
await self._stop_fleet()
async def _stop_fleet(self) -> None:
for slot in list(self._fleet):
await self._stop_slot(slot)
slots = list(self._fleet)
if slots:
await asyncio.gather(*(self._stop_slot(slot) for slot in slots), return_exceptions=True)
async def _stop_slot(self, slot: int) -> None:
entry = self._fleet.pop(slot, None)
@@ -150,8 +151,20 @@ class BotsService(BaseService):
pass
except Exception as e:
self.log(f"bot{slot} stop error: {e}")
await self._close_bot(slot, entry.get("bot"))
self.log(f"Stopped bot{slot}")
async def _close_bot(self, slot: int, bot) -> None:
browser = getattr(bot, "b", None)
if browser is None:
return
try:
await asyncio.wait_for(browser.close(), timeout=15)
except (asyncio.CancelledError, asyncio.TimeoutError):
pass
except Exception as e:
self.log(f"bot{slot} browser close error: {e}")
def collect_metrics(self) -> dict:
rows = []
total_cost = 0.0