diff --git a/litecord/voice/lvsp_manager.py b/litecord/voice/lvsp_manager.py index 19e5098..8186a9f 100644 --- a/litecord/voice/lvsp_manager.py +++ b/litecord/voice/lvsp_manager.py @@ -17,6 +17,14 @@ along with this program. If not, see . """ +from collections import defaultdict + +from logbook import Logger + +from litecord.voice.lvsp_conn import LVSPConnection + +log = Logger(__name__) + class LVSPManager: """Manager class for Litecord Voice Server Protocol (LVSP) connections. @@ -25,3 +33,50 @@ class LVSPManager: def __init__(self, app, voice): self.app = app self.voice = voice + + self.servers = defaultdict(dict) + self.app.loop.create_task(self._spawn()) + + async def _spawn(self): + """Spawn LVSPConnection for each region.""" + + regions = await self.app.db.fetchval(""" + SELECT id + FROM voice_regions + WHERE deprecated = false + """) + + for region in regions: + self.app.loop.create_task( + self._spawn_region(region) + ) + + async def _spawn_region(self, region: str): + """Spawn a region. Involves fetching all the hostnames + for the regions and spawning a LVSPConnection for each.""" + servers = await self.app.db.fetch(""" + SELECT hostname + FROM voice_servers + WHERE region_id = $1 + """, region) + + if not servers: + log.warning('region {} does not have servers', region) + return + + servers = [r['hostname'] for r in servers] + + for hostname in servers: + conn = LVSPConnection(self, region, hostname) + self.servers[region][hostname] = conn + + self.app.loop.create_task( + conn.run() + ) + + async def del_conn(self, conn): + """Delete a connection from the connection pool.""" + try: + self.servers[conn.region].pop(conn.hostname) + except KeyError: + pass