feat(backend): presence stats count time online from sessions in the browser time zone, capture uptime marks hours without data, presence reaches every stream of the account, message volume keeps empty days

This commit is contained in:
hh committed 2026-10-19 02:41:39 +00:00
1 parent bb38e23f29
commit f44597b2dc
14 files changed
+585 -26

No files matched your search

+13
View File
@@ -14,6 +14,7 @@ from userbot.modules.capture import CaptureContext, build_capture_context
from userbot.modules.catchup import SavedState, catch_up, read_saved_state
from userbot.modules.client import PyroClient
from userbot.modules.jobs import JobConsumer
from userbot.modules.uptime import repository as uptime
from utils.env import env
from utils.jobs import enqueue
from utils.listen import Listener
@@ -31,6 +32,7 @@ setup_logging()
SESSION_FLUSH_INTERVAL = 60
SESSION_RETRY_INTERVAL = 60
UPTIME_INTERVAL = 60
@dataclass
@@ -171,6 +173,15 @@ async def _retry_sessions(registry: AccountRegistry) -> None:
logger.exception("[red]Session sync failed[/]")
async def _keep_uptime(registry: AccountRegistry, pool: asyncpg.Pool) -> None:
while True:
for client in registry.clients:
if client.capture is not None and client.is_connected:
with contextlib.suppress(Exception):
await uptime.heartbeat(pool, client.capture.account_id)
await asyncio.sleep(UPTIME_INTERVAL)
def _change_listener(registry: AccountRegistry, tasks: set[asyncio.Task]) -> Listener:
def spawn(coro: Coroutine[Any, Any, None]) -> None:
task = asyncio.create_task(coro)
@@ -220,6 +231,7 @@ async def runner() -> None:
asyncio.get_running_loop().add_signal_handler(signal.SIGTERM, stop.set)
flush = asyncio.create_task(_flush_sessions(registry))
retry = asyncio.create_task(_retry_sessions(registry))
beat = asyncio.create_task(_keep_uptime(registry, pool))
try:
await registry.sync()
if not registry.clients:
@@ -230,6 +242,7 @@ async def runner() -> None:
finally:
await _cancel(flush)
await _cancel(retry)
await _cancel(beat)
await listener.stop()
await registry.close()
await container.close()