forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   PHP / MySQL (http://forum.boolean.name/forumdisplay.php?f=135)
-   -   Результаты совместной "игры" (http://forum.boolean.name/showthread.php?t=19252)

pax 17.06.2014 12:38

Результаты совместной "игры"
 
Допустим есть некие таблицы:

games - созданные игры
games_activity - лог активности игроков в играх (лог всех важных действий, по которым надо будет посчитать результаты)
games_users - статистика игрока в игре (например количество респавнов, когда вошел в игру и т.д.)

Происходит завершение игры, как правильно это обработать на сервере? Надо чтобы сервер на php посчитал результаты и выдал их каждому игроку. Как это лучше организовать?


Пока мысли такие: первый запросивший результаты пишет в Redis флаг, что он начал обрабатывать результаты, остальные наткнувшись на такой флаг начинают ждать и опрашивать Redis завершения обработки результатов. Это нормальный подход или есть какие-то классические подходы для решения таких задач? PS: Я к php еще никак не привыкну, поэтому возникают такие вопросы.

moka 17.06.2014 14:39

Ответ: Результаты совместной "игры"
 
Думаю тут PHP "не причем".
По объему данных, какие прогнозы - сколько займет просчет?

Стоит ли обрабатывать это дело в PHP, или использовать отдельный процесс, который тупо заточен на обработку именно этих данных для генерации данных о завершении игры.
Такой вариант имеет немного больше свободы технически, но при этом имеет чуток больше проблем тоже.

Делать запрос в PHP и блокировать его до тех пор пока не получишь результаты - немного "грубо". Если есть WS транспорт, то используй его, если нету, тогда делай лучше переодические запросы.

По завершению игры, используй SETNX, где key будет ID игровой сессии и value будет 1. Это атомарный метод создает запись если она не создана и возвращает 1, если запись уже есть возвратит 0.
Таким образом ты будешь "уверен" что только один процесс начал обработку. Также если обработка может зафейлиться, то нужно делать таймаут на этот key и "кто-то" должен проверять не обработанные игры, и обрабатывать их.

При этом клиенты пусть запрашивают данные с другого endpoint'а (/games/.../results), которые тупо будут грузить данные из таблицы games_results, если данные не существуют, проверять если в redis'е есть запись (которую ранее создали), если есть, значит данные обрабатываются, если нету - значит таких результатов вообще нету.

Если данные обрабатываются, то пусть /results возвратит "данные обрабатываются", и клиент просто будет запрашивать их каждые 500мс (например). Не забудь timeout на записи в redis'е как уже упомянул ранее, чтобы если обработка результатов зафейлит, хотя бы клиенты не застопорятся в ожидании результатов.


Естественно подобные вещи лучше делать имея messaging сервер, который является обменной точкой разных сообщений, например о результатах игры, или приглашении кого-то на рейс и т.п.
Такой сервер используется для обмена разного рода сообщениями и нотификациями.

pax 18.06.2014 00:50

Ответ: Результаты совместной "игры"
 
Спасибо за совет, думаю данных будет не очень много на обработку и я вероятно попробую решить часть задачи во время выполнения самих эвентов. Т.е. попробую посчитать результат для каждого игрока во время игры и дополнять его по мере поступления эвентов. Если такой способ не прокатит, буду пробовать SETNX. С таймаутом тоже спасибо, возьму на заметку.


Часовой пояс GMT +4, время: 14:18.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot