Fixing error when stop and return too fast, because of that there may be some threads downloading songs that will try to put songs in a already closed queue

This commit is contained in:
Rafael Vargas
2023-01-25 13:07:39 -03:00
parent 8dfa3579ae
commit afb223eadd
12 changed files with 51 additions and 15 deletions

View File

@@ -197,6 +197,15 @@ class PlayerProcess(Process):
self.__loop.create_task(self.__playSong(song), name=f'Song {song.identifier}')
async def __restartCurrentSong(self) -> None:
song = self.__playlist.getCurrentSong()
if song is None:
song = self.__playlist.next_song()
if song is None:
return
self.__loop.create_task(self.__playSong(song), name=f'Song {song.identifier}')
def __commandsReceiver(self) -> None:
while True:
command: VCommands = self.__queueReceive.get()
@@ -210,7 +219,7 @@ class PlayerProcess(Process):
elif type == VCommandsType.RESUME:
self.__resume()
elif type == VCommandsType.SKIP:
self.__skip()
asyncio.run_coroutine_threadsafe(self.__skip(), self.__loop)
elif type == VCommandsType.PLAY:
asyncio.run_coroutine_threadsafe(self.__playPlaylistSongs(), self.__loop)
elif type == VCommandsType.PREV:
@@ -265,12 +274,14 @@ class PlayerProcess(Process):
if self.__guild.voice_client.is_paused():
self.__guild.voice_client.resume()
def __skip(self) -> None:
async def __skip(self) -> None:
# Lock to work with Player
with self.__playerLock:
if self.__guild.voice_client is not None and self.__playing:
self.__playing = False
self.__guild.voice_client.stop()
elif len(self.__playlist) > 0: # If for some reason the Bot has disconnect but there is still songs to play
await self.__restartCurrentSong()
async def __forceStop(self) -> None:
# Lock to work with Player

View File

@@ -28,9 +28,9 @@ class ProcessManager(Singleton):
VManager.register('Playlist', Playlist)
self.__manager = VManager()
self.__manager.start()
self.__playersProcess: Dict[Guild, ProcessInfo] = {}
self.__playersListeners: Dict[Guild, Tuple[Thread, bool]] = {}
self.__playersCommandsExecutor: Dict[Guild, ProcessCommandsExecutor] = {}
self.__playersProcess: Dict[int, ProcessInfo] = {}
self.__playersListeners: Dict[int, Tuple[Thread, bool]] = {}
self.__playersCommandsExecutor: Dict[int, ProcessCommandsExecutor] = {}
def setPlayerInfo(self, guild: Guild, info: ProcessInfo):
self.__playersProcess[guild.id] = info
@@ -96,8 +96,24 @@ class ProcessManager(Singleton):
return processInfo
def __stopPossiblyRunningProcess(self, guild: Guild):
try:
if guild.id in self.__playersProcess.keys():
playerProcess = self.__playersProcess.popitem(guild.id)
process = playerProcess.getProcess()
process.close()
process.kill()
playerProcess.getQueueToMain().close()
playerProcess.getQueueToMain().join_thread()
playerProcess.getQueueToPlayer().close()
playerProcess.getQueueToPlayer().join_thread()
except Exception as e:
print(f'[ERROR STOPPING PROCESS] -> {e}')
def __recreateProcess(self, guild: Guild, context: Union[Context, Interaction]) -> ProcessInfo:
"""Create a new process info using previous playlist"""
self.__stopPossiblyRunningProcess(guild)
guildID: int = context.guild.id
textID: int = context.channel.id
if isinstance(context, Interaction):