"""Pub/sub messaging bus for chat events over Redis. Provides asynchronous publish hooks for world/room chat and DMs, allowing the WebSocket real-time gateway (and multi-instance replicas) to receive and fan out chat messages in real time. """ from __future__ import annotations import json import logging from typing import Any import redis.asyncio as aioredis from app.config import settings logger = logging.getLogger(__name__) async def publish_world_chat_event( world_id: int, payload: dict[str, Any], room_id: int | None = None ) -> None: """Publish a world chat message event to Redis pub/sub for real-time delivery.""" try: client = aioredis.from_url(settings.REDIS_URL, encoding="utf-8", decode_responses=True) async with client: channel = f"world:{world_id}:chat" data = json.dumps(payload, default=str) await client.publish(channel, data) if room_id is not None: await client.publish(f"room:{room_id}:chat", data) except Exception as exc: logger.debug("Failed to publish world chat event to Redis: %s", exc) async def publish_dm_chat_event( conversation_id: int, payload: dict[str, Any] ) -> None: """Publish a DM chat message event to Redis pub/sub for real-time delivery.""" try: client = aioredis.from_url(settings.REDIS_URL, encoding="utf-8", decode_responses=True) async with client: channel = f"dm:{conversation_id}:chat" data = json.dumps(payload, default=str) await client.publish(channel, data) except Exception as exc: logger.debug("Failed to publish DM chat event to Redis: %s", exc)