Задать вопрос

Как обработать истечение срока?

Имеются модели Task(задание), Skill(навык). Задание создает человек, ему он указывает срок выполнения deadline_at. Skill имеет поле score(количество очков у навыка). К заданию вы можете через промеж. таблицу присоединять навыки и указывать как они изменятся при выполнении/ невыполнении задания.

Пример
Есть задание Подкачаться
Юзер указывает, что при выполнении навык сила получит 5 очков, иначе же навык потеряет 10.
При очередном заходе на страницу юзер видит, что срок выполнения истек, и задание подкачаться провалено, а навык сила потерял 10 очков.

Так вот, как же сделать эту обработку задний. Нужно неведомым мне образом чекать бд и при наличии заданий, у коих срок истек, выставлять им поле finished_at и обновлять привязанные скилы.
Я пробовал делать это через Task Scheduler. В принципе все работало: каждую минуту в бд посылался запрос, находились необходимые задания и выполнялось обновление как скилов, так и заданий
Но вот проблема. Этот поиск идет раз в минуту. Но что если срок у задания истечет в промежутке между работай Task Scheduler, тогда при заходе на страницу задания юзер увидит, что срок истек, но задание не отмечено законченным, а привязанные к нему скилы не потеряли очков.

Как с этим бороться? И вообще как реализована в больших проектах проверка на истечение срока.(истории в ВК, которые удаляются через 24 ч). Ведь фишка в том, что нужно не просто фильтровать таблицу через where(...), а нужно еще и обновлять ее при необходимости и все это должно происходить до начала работы осн. логики проекта
  • Вопрос задан
  • 158 просмотров
Подписаться 1 Простой 1 комментарий
Решения вопроса 1
JhaoDa
@JhaoDa
LaravelRUS Team
Раз в N минут собирать собирать задания, которым скоро подойдёт срок. Ставить в очередь их удаление с точностью до минуты/секунды.

P.S. И поменьше тэгов.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
FeNUMe
@FeNUMe
Имхо для описанной вами задачи вообще нет смысла дергать постоянно базу и выставлять флаг, вместо этого в клиентской части просто делайте проверку
текущее_время > deadline_at
и на основе результата проводите нужные манипуляции.
Ответ написан
Комментировать
Учите очереди, при создании задания добавляете на момент его окончания задачу проверить, истекло ли конкретно это задание (и не обработано ли оно ещё), плюс, реализуете совет от FeNUMe на случай если задания будут исполнены раньше срока (для этого и нужна первая проверка на то, исполнена задача или нет. В идеале ту. Бы удалить задачу из очереди, но ларавел на текущий момент этого не позволяет). Если сделаете то, что отметили решением, то когда задач не будет, ваши ресурсы будут работать вхолостую, отнимая процессорное время (на это наплевать, пока вы не перешли на оплату за ресурсы, но зачем приучаться к говнокоду?), а когда (если) сервис станет огромным и задач станет слишком много, он будет захлёбываться в задачах, очереди же равномерно распределят нагрузку и не дадут вам наговнокодить в попытке решить эту проблему, так как их можно распараллелить на несколько потоков.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы