mirror of
https://github.com/RafaelSolVargas/Vulkan.git
synced 2025-10-29 16:57:23 +00:00
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:
parent
8dfa3579ae
commit
afb223eadd
@ -9,7 +9,7 @@ class VConfigs(Singleton):
|
||||
if not super().created:
|
||||
# You can change this boolean to False if you want to prevent the Bot from auto disconnecting
|
||||
# Resolution for the issue: https://github.com/RafaelSolVargas/Vulkan/issues/33
|
||||
self.SHOULD_AUTO_DISCONNECT_WHEN_ALONE = True
|
||||
self.SHOULD_AUTO_DISCONNECT_WHEN_ALONE = False
|
||||
|
||||
self.BOT_PREFIX = '!'
|
||||
try:
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from Parallelism.Commands import VCommands
|
||||
from multiprocessing import Queue
|
||||
from typing import List, Union
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client, Guild, ClientUser, Interaction, Member, User
|
||||
@ -27,6 +29,12 @@ class AbstractHandler(ABC):
|
||||
else:
|
||||
self.__author = ctx.user
|
||||
|
||||
def putCommandInQueue(self, queue: Queue, command: VCommands) -> None:
|
||||
try:
|
||||
queue.put(command)
|
||||
except Exception as e:
|
||||
print(f'[ERROR PUTTING COMMAND IN QUEUE] -> {e}')
|
||||
|
||||
@abstractmethod
|
||||
async def run(self) -> HandlerResponse:
|
||||
pass
|
||||
|
||||
@ -50,7 +50,7 @@ class JumpMusicHandler(AbstractHandler):
|
||||
# Send a command to the player to skip the music
|
||||
command = VCommands(VCommandsType.SKIP, None)
|
||||
queue = processInfo.getQueueToPlayer()
|
||||
queue.put(command)
|
||||
self.putCommandInQueue(queue, command)
|
||||
|
||||
processLock.release()
|
||||
return HandlerResponse(self.ctx)
|
||||
|
||||
@ -23,7 +23,7 @@ class PauseHandler(AbstractHandler):
|
||||
# Send Pause command to be execute by player process
|
||||
command = VCommands(VCommandsType.PAUSE, None)
|
||||
queue = processInfo.getQueueToPlayer()
|
||||
queue.put(command)
|
||||
self.putCommandInQueue(queue, command)
|
||||
|
||||
embed = self.embeds.PLAYER_PAUSED()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
@ -75,7 +75,8 @@ class PlayHandler(AbstractHandler):
|
||||
processLock.release()
|
||||
queue = processInfo.getQueueToPlayer()
|
||||
playCommand = VCommands(VCommandsType.PLAY, None)
|
||||
queue.put(playCommand)
|
||||
self.putCommandInQueue(queue, playCommand)
|
||||
|
||||
else:
|
||||
processManager.resetProcess(self.guild, self.ctx)
|
||||
embed = self.embeds.PLAYER_RESTARTED()
|
||||
@ -135,7 +136,7 @@ class PlayHandler(AbstractHandler):
|
||||
acquired = processLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
||||
if acquired:
|
||||
playlist.add_song(song)
|
||||
queue.put(playCommand)
|
||||
self.putCommandInQueue(queue, playCommand)
|
||||
processLock.release()
|
||||
else:
|
||||
processManager.resetProcess(self.guild, self.ctx)
|
||||
|
||||
@ -44,7 +44,7 @@ class PrevHandler(AbstractHandler):
|
||||
# Send a prev command, together with the user voice channel
|
||||
prevCommand = VCommands(VCommandsType.PREV, self.author.voice.channel.id)
|
||||
queue = processInfo.getQueueToPlayer()
|
||||
queue.put(prevCommand)
|
||||
self.putCommandInQueue(queue, prevCommand)
|
||||
|
||||
embed = self.embeds.RETURNING_SONG()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
@ -23,7 +23,7 @@ class ResetHandler(AbstractHandler):
|
||||
|
||||
command = VCommands(VCommandsType.RESET, None)
|
||||
queue = processInfo.getQueueToPlayer()
|
||||
queue.put(command)
|
||||
self.putCommandInQueue(queue, command)
|
||||
|
||||
return HandlerResponse(self.ctx)
|
||||
else:
|
||||
|
||||
@ -23,7 +23,7 @@ class ResumeHandler(AbstractHandler):
|
||||
# Send Resume command to be execute by player process
|
||||
command = VCommands(VCommandsType.RESUME, None)
|
||||
queue = processInfo.getQueueToPlayer()
|
||||
queue.put(command)
|
||||
self.putCommandInQueue(queue, command)
|
||||
|
||||
embed = self.embeds.PLAYER_RESUMED()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
@ -29,7 +29,7 @@ class SkipHandler(AbstractHandler):
|
||||
# Send a command to the player process to skip the music
|
||||
command = VCommands(VCommandsType.SKIP, None)
|
||||
queue = processInfo.getQueueToPlayer()
|
||||
queue.put(command)
|
||||
self.putCommandInQueue(queue, command)
|
||||
|
||||
embed = self.embeds.SKIPPING_SONG()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
@ -23,7 +23,7 @@ class StopHandler(AbstractHandler):
|
||||
# Send command to player process stop
|
||||
command = VCommands(VCommandsType.STOP, None)
|
||||
queue = processInfo.getQueueToPlayer()
|
||||
queue.put(command)
|
||||
self.putCommandInQueue(queue, command)
|
||||
|
||||
embed = self.embeds.STOPPING_PLAYER()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user