Проблема с таймером Django

Я пишу шахматное приложение с помощью Django и Django Channels. Проблема, с которой я столкнулся, заключается в следующем: Во время игры, каждый раз, когда игрок делает ход, таймер противника начинает отсчитывать время. Мне удалось добиться этого с помощью задач. Проблема в том, что каждый раз, когда цикл уменьшает таймер и передает оба таймера клиентам, он обращается к базе данных и сохраняет текущее значение таймера в модели. Это происходит каждую секунду, и я понял, что это плохая практика (сохранение в базу данных каждую секунду), и это вызывает у меня некоторые ошибки. Мой вопрос в том, какой подход здесь правильный? Я хочу отслеживать таймеры на стороне бэкенда, чтобы, например, когда он достигнет нуля, я мог остановить игру, или когда игрок отключится, таймер продолжит отсчет.

async def timer_handler(self, event):
        moving_color = event['text']
        username = self.scope['user'].username
        consumer_color = self.game_obj.get_color(username)
        if consumer_color == moving_color:
            if self.timer_task != None:
                asyncio.Task.cancel(self.timer_task)
                self.timer_task = None
        elif consumer_color == self.opposite_color(moving_color):
            if self.timer_task == None:
                self.timer_task = asyncio.create_task(self.timer_countdown(self.opposite_color(moving_color)))
            else:
                try:
                    raise Exception("Scheduled a timer task for a timer that's already running")
                finally:
                    print('self.timer_task:', self.timer_task)

    
    async def timer_countdown(self, color):
        timer = self.get_timer(color)
        while True:
            await asyncio.sleep(1)
            timer -= 1
            await database_sync_to_async(self.update_timer)(timer, color)
            timer_formatted = self.to_timer_format(timer)
            data = {
                'type': 'time',
                'time': timer_formatted,
                'timer_color': color
            }
            await self.channel_layer.group_send(
                self.game_room_name,
                {
                    'type': 'basic_broadcast',
                    'text': data
                }
            )

    def update_timer(self, time, timer_color):
        game_obj = Game.objects.get(id=self.game_id)
        if timer_color == 'white':
            game_obj.timer_white = time
        elif timer_color == 'black':
            game_obj.timer_black = time
        else:
            try:
                raise Exception('Undefined timer color')
            finally:
                print('timer_color:', timer_color)
        game_obj.save()

Функция timer_handler вызывается каждый раз, когда игрок делает ход. ссылка на весь проект: https://github.com/mephis71/django_chess

Вернуться на верх