Answer the question
In order to leave comments, you need to log in
APSheduler. How to store a class method in the task store?
There is a SocketServer class. It has a self.__room_thread() method. It also has an instance of the BackgroundScheduler() scheduler. This class has access to a PostgreSQL database. I need to save and load scheduled events to / from the database. But these events are handled by the self.__room_thread() method. And this is where the problems begin. First, the class whose method is being used as the handler must not contain an instance of the scheduler. Okay, that's not a problem. Removed. It worked, but not for long. Further errors like the forbidden reference to a method rained down. Those. because self.__room_thread() is declared "private", the scheduler cannot run it. OK. Made "public". Further errors rained down on each object of a class used inside. Those. essentially the same error as with self.__room_thread(), only now with each of the other fields/methods of the class. In general, I very much ask for your help, how can I still implement this, in my opinion, trivial task through APScheduler?
The code:
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}")
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question