Подтвердить что ты не робот

Вопрос проектирования: как бы вы создали повторяющуюся систему событий?

Если вам было поручено создать систему планирования событий, поддерживающую повторяющиеся события, как бы вы это сделали? Как вы справляетесь с удалением повторяющегося события? Как вы могли видеть, когда будут происходить будущие события?

то есть. При создании события вы можете выбрать "повторять ежедневно" (или еженедельно, ежегодно и т.д.).

Один дизайн за ответ, пожалуйста. Я привык к Ruby/Rails, но использую то, что вы хотите выразить.

Меня спросили об этом на собеседовании и не смогли придумать действительно хороший ответ, который мне понравился.

Примечание: был уже задан/ответил здесь. Но я надеялся получить более практичные детали, как описано ниже:

  • Если необходимо было иметь возможность комментировать или иным образом добавлять данные только к одному экземпляру повторяющегося события, как это работает?
  • Как будут происходить изменения и удаления событий?
  • Как вы рассчитываете, когда происходят будущие события?
4b9b3361

Ответ 1

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

Следующая проблема заключалась в выяснении того, как в мире хранить выражения. Другая проблема заключается в том, когда вы читаете выражение, как они вписываются в не столь динамичный пользовательский интерфейс? Были разговоры о простое сериализация выражений в BLOB, но было бы трудно пройти дерево выражений, чтобы узнать, что это означало.

Решение (в моем случае) - хранить параметры, которые соответствуют ограниченному числу случаев, которые поддерживает пользовательский интерфейс, и оттуда использовать эту информацию для генерации временных выражений "на лету" (может быть сериализовано при создании для оптимизации), Таким образом, класс Schedule заканчивается тем, что имеет несколько параметров, таких как смещение, дата начала, дата окончания, день недели и т.д.... и из этого вы можете генерировать временные выражения для выполнения тяжелой работы.

Что касается наличия экземпляров задач, существует "служба", которая генерирует задачи для N дней. Поскольку это интеграция с существующей системой, и все экземпляры необходимы, это имеет смысл. Однако такой API можно легко использовать для прогнозирования повторений без сохранения всех экземпляров.

Ответ 2

Мне приходилось делать это раньше, когда я управлял концом базы данных проекта. Я попросил, чтобы каждое событие хранилось как отдельные события. Это позволяет удалить только одно событие или вы можете переместить диапазон. Намного проще удалить кратные, чем попытаться изменить одно вхождение и превратить его в два. Затем мы смогли создать еще одну таблицу, в которой просто был идентификатор recurrenceID, содержащий информацию о повторении.

Ответ 3

@Joe Van Dyk спросил: "Не могли бы вы посмотреть в будущее и посмотреть, когда будут предстоящие события?"

Если вы хотите видеть/отображать следующие n событий события, они должны были бы либо a) рассчитываться заранее и храниться где-то, либо b ) рассчитывается на лету и отображается. Это было бы одинаково для любых вечерних рамок.

Недостатком a) является то, что вы должны наложить на него предел, а после этого вы должны использовать b). Легче просто использовать б) для начала.

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

Ответ 4

При сохранении события я бы сохранил расписание в хранилище (позвольте ему " Расписания" ), и я бы вычислил, когда событие должно было запустить в следующий раз и сохранить это также, для экземпляр в " События". Затем я просмотрю " События" и выясню, когда должно было произойти следующее событие и спать до тех пор.

Когда приложение "проснется", оно подсчитает, когда событие должно произойти снова, сохраните его в " События" и затем выполните событие.

Повторить.

Если во время сна создается событие, сон прерывается и пересчитывается.

Если приложение запускается или восстанавливается из события сна или аналогичного, отметьте " События" для прошедших событий и действуйте соответствующим образом (в зависимости от того, что вы хотите делать с пропущенными событиями).

Что-то вроде этого будет гибким и не потребует ненужных циклов процессора.

Ответ 5

Сверху моей головы (после пересмотра пары вещей при вводе/мышлении):

Определите минимальное требуемое разрешение повторения; как часто приложение работает. Может быть, это ежедневно, может быть, каждые пять минут.

Для каждого повторяющегося события сохраняйте самое последнее время выполнения, интервал выполнения и другие свойства, такие как время истечения, если это желательно.

Каждый раз, когда приложение запускается, оно проверяет все события, сравнивая (today/now + recurrenceResolution) с (recentRunTime + runInterval), и если они совпадают, запустите это событие.

Ответ 6

Когда я написал приложение для календаря для себя, много лет назад, я просто просто украл механизм планирования из cron и использовал его для повторяющихся событий. например, что-то, что происходит во вторую субботу каждого месяца, кроме января, будет включать инструкцию "repeat = * 2-12 8-14 6" (каждый год, месяцы 2-12, вторая неделя проходит с 8-го по 14-й, и 6 в субботу, потому что я использовал нумерацию на основе 0 для дней недели).

Несмотря на то, что это довольно легко определить, происходит ли событие в любую заданную дату, оно не способно обрабатывать повторение "каждый N дней", а также менее интуитивно понятное для пользователей, которые не являются совместимыми с Linux.

Чтобы иметь дело с уникальными данными для отдельных экземпляров событий и удаления/перепланирования, я просто отслеживал, как были рассчитаны события вне событий и хранятся результирующие события в базе данных, где они затем могут быть изменены, перемещены или удалены не влияя на исходную текущую информацию о событиях. Когда было добавлено новое повторяющееся событие, все экземпляры сразу вычислялись до текущей "последней расчетной" даты.

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

Ответ 7

Если у вас есть простое повторное событие, такое как ежедневное, еженедельное или пару дней в неделю, что случилось с использованием buildt в scheduler/cron/at functionallity? Создание исполняемого/консольного приложения и настройка, когда его запускать? Нет сложного календаря, события или времени.

:)

//W