""" Entry point — starts all async tasks concurrently: 1. StreamKar WebSocket client (anonymous, captures user bets) 2. Game state HTTP poller (authenticated, captures full game state) 3. aiohttp web server (serves dashboard, pushes events to browsers) """ import asyncio import logging import signal from .server import WebServer from .streamkar_ws import StreamKarWSClient from .game_poller import GamePoller from . import db logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(name)s] %(levelname)s: %(message)s", datefmt="%H:%M:%S", ) log = logging.getLogger(__name__) async def main(): server = WebServer() ws_client = StreamKarWSClient(broadcast_fn=server.broadcast) poller = GamePoller(broadcast_fn=server.broadcast, push_refresh_fn=server.push_refresh) loop = asyncio.get_event_loop() def shutdown(): log.info("Shutting down...") ws_client.stop() poller.stop() for task in asyncio.all_tasks(loop): task.cancel() for sig in (signal.SIGINT, signal.SIGTERM): loop.add_signal_handler(sig, shutdown) log.info("Starting Teen Patti Live Monitor") await loop.run_in_executor(None, db.run_migrations) log.info("Dashboard: http://localhost:8765") tasks = [ asyncio.create_task(server.run(), name="web_server"), asyncio.create_task(poller.run(), name="game_poller"), asyncio.create_task(ws_client.run(), name="ws_client"), ] try: await asyncio.gather(*tasks) except asyncio.CancelledError: pass except Exception as e: log.error("Fatal: %s", e) finally: log.info("Stopped.") if __name__ == "__main__": asyncio.run(main())