diff --git a/redbot/cogs/audio/core/tasks/lavalink.py b/redbot/cogs/audio/core/tasks/lavalink.py index b952cc130..b94f36eed 100644 --- a/redbot/cogs/audio/core/tasks/lavalink.py +++ b/redbot/cogs/audio/core/tasks/lavalink.py @@ -56,7 +56,9 @@ class LavalinkTasks(MixinMeta, metaclass=CompositeMetaClass): password = configs["yaml"]["lavalink"]["server"]["password"] secured = False # Make this timeout customizable for lower powered machines? - self.managed_node_controller = ServerManager(self.config, timeout=60, cog=self) + self.managed_node_controller = ServerManager( + self.config, timeout=60, download_timeout=60 * 3, cog=self + ) try: await self.managed_node_controller.start(java_exec) # timeout is the same as ServerManager.timeout - diff --git a/redbot/cogs/audio/manager.py b/redbot/cogs/audio/manager.py index 93ad89e3d..4e750da26 100644 --- a/redbot/cogs/audio/manager.py +++ b/redbot/cogs/audio/manager.py @@ -125,13 +125,21 @@ class ServerManager: _buildtime: ClassVar[Optional[str]] = None _java_exc: ClassVar[str] = "java" - def __init__(self, config: Config, cog: "Audio", timeout: Optional[int] = None) -> None: + def __init__( + self, + config: Config, + cog: "Audio", + timeout: Optional[int] = None, + download_timeout: Optional[int] = None, + ) -> None: self.ready: asyncio.Event = asyncio.Event() + self.downloaded: asyncio.Event = asyncio.Event() self._config = config self._proc: Optional[asyncio.subprocess.Process] = None # pylint:disable=no-member self._shutdown: bool = False self.start_monitor_task = None self.timeout = timeout + self.download_timeout = download_timeout self.cog = cog self._args = [] self._pipe_task = None @@ -357,6 +365,7 @@ class ServerManager: async def _partial_shutdown(self) -> None: self.ready.clear() + self.downloaded.clear() if self._shutdown is True: # For convenience, calling this method more than once or calling it before starting it # does nothing. @@ -414,6 +423,7 @@ class ServerManager: log.info("Successfully downloaded Lavalink.jar (%s bytes written)", format(nbytes, ",")) await self._is_up_to_date() + self.downloaded.set() async def _is_up_to_date(self): if self._up_to_date is True: @@ -487,8 +497,14 @@ class ServerManager: managed_node.JAR_VERSION, ) await self._download_jar() + else: + self.downloaded.set() - async def wait_until_ready(self, timeout: Optional[float] = None): + async def wait_until_ready( + self, timeout: Optional[float] = None, download_timeout: Optional[float] = None + ): + download_timeout = download_timeout or self.download_timeout + await asyncio.wait_for(self.downloaded.wait(), timeout=download_timeout) await asyncio.wait_for(self.ready.wait(), timeout=timeout or self.timeout) async def start_monitor(self, java_path: str): @@ -499,6 +515,7 @@ class ServerManager: self._shutdown = False if self._proc is None or self._proc.returncode is not None: self.ready.clear() + self.downloaded.clear() await self._start(java_path=java_path) while True: await self.wait_until_ready(timeout=self.timeout)