@Sazoks

APSheduler. Как сохранить метод класса в хранилище задач?

Есть класс SocketServer. В нем есть метод self.__room_thread(). Также в нем есть экземпляр планировщика BackgroundScheduler(). Этот класс имеет доступ к БД PostgreSQL. Мне нужно, сохранять и загружать в/из базы данных запланированные события. Но эти события обрабатываются методом self.__room_thread(). И тут начинаются проблемы. Во-первых, класс, чей метод используется в качестве обработчика, не должен содержать в себе экземпляр планировщика. Окей, это не проблема. Убрал. Заработало, но не надолго. Дальше посыпались ошибки по типу запрещенной ссылки на метод. Т.е. из-за того, что self.__room_thread() объявлен как "private", планировщик не может его запустить. Окей. Сделал "public". Дальше посыпались ошибки на каждый используемый внутри объект класса. Т.е. по сути та же ошибка, что и с self.__room_thread(), только теперь с каждый из других полей/методов класса. В общем, очень сильно прошу вашей помощи, как же мне все-таки реализовать данную, на мой взгляд, тривиальную задачу через APScheduler?
Код:
class SocketServer:
"""
Класс сокетного сервера.
Обрабатывает все запросе пользователей к серверу через сокеты.
Обеспечивает трансляцию игр пользователям.
"""

def __init__(self, socket: SocketIO, db_connector: DatabaseConnector, scheduler):
    """
    Инициализатор класса.
    :param socket: Серверный сокет для общения с клиентами.
    :param db_connector: Ссылка на коннектор базы данных.
    """

    ############################ ТЕСТОВЫЙ КОД ##########################
    self.__ex = [
        Event(0, "event_0", datetime.datetime(2021, 4, 14, 21, 54, 0),
              GameSnake(), [], "room_0", False),
        Event(1, "event_1", datetime.datetime(2021, 4, 14, 21, 54, 20),
              GameSnake(), [], "room_1", False),
        Event(2, "event_2", datetime.datetime(2021, 4, 14, 21, 54, 30),
              GameSnake(), [], "room_2", False)
    ]
    for e in self.__ex:
        scheduler.add_job(self.__room_thread, "date", 
                          run_date=e.get_run_date(), args=[e])
    ###################################################################

    # Коннектор бд.
    self.__db_connector = db_connector
    # Наш серверный сокет.
    self.__socket_io = socket
    # Список комнат.
    self.__list_rooms = []

    # Запускаем обработчики.
    self.connect_client = self.__socket_io.on("connect")(self.__connect_client)
    self.disconnect_client = self.__socket_io.on("disconnect")(self.__disconnect_client)
    self.client_join_room = self.__socket_io.on("join")(self.__client_join_room)
    self.client_leave_room = self.__socket_io.on("leave")(self.__client_leave_room)

def __room_thread(self, event: Event):
    """
    Метод запуска комнаты в потоке.
    :param event: Обрабатываемое событие в потоке.
    :return:
    """

    with Lock():
        self.__list_rooms.append(event.get_room())

    # Скорость трансляции.
    broadcast_delay = 0.4
    # Рассчитываем всю игру.
    # После этого у нас есть готовая история игры в game.
    event.get_game().calculation_game()

    # Транслируем историю пошагово.
    for game_step in event.get_game().get_history():
        self.__socket_io.emit("message", game_step, room=event.get_room())
        time.sleep(broadcast_delay)

    # Если записи не должно быть - удаляем.
    if not event.get_record_avail():
        event.get_game().delete_history()
    else:
        # Если запись есть, сохраняем.
        pass

    # Используем мьютекс для синхронизации потоков.
    with Lock():
        # По окончании трансляции удаляем комнату и поток.
        for i, room in enumerate(self.__list_rooms):
            if room == event.get_room():
                self.__list_rooms.pop(i)
                print(f"{room} deleted")
                break

@staticmethod
def __connect_client():
    """Подключение клиента"""
    print("Client connected")

@staticmethod
def __disconnect_client():
    """Отключение клиента"""
    print("Client disconnected")

def __client_join_room(self, data: Dict[str, str]):
    """
    Метод подключения клиента в комнату.
    :param data: Данные пользователя. Приходят с клиента.
    :return:
    """

    username = data["username"]
    name_room = data["room"]

    if name_room not in self.__list_rooms:
        print(f"{name_room} not started")
    else:
        join_room(name_room)
        print(f"{username}'s connected to {name_room}")

def __client_leave_room(self, data: Dict):
    """
    Метод отключения клиента от комнаты.
    :param data: Данные пользователя. Приходят с клиента.
    :return:
    """

    username = data["username"]
    name_room = data["room"]

    if name_room not in self.__list_rooms:
        print(f"{name_room} not exist")
    else:
        leave_room(name_room)
        print(f"{username}'s disconnected from {name_room}")
  • Вопрос задан
  • 26 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы