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

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

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

ReportScheduler
---------------
AutoID int
MemberID VarChar(6)
ReportID int
RunWhen DateTime

... но вскоре понял, что «RunWhen» не собирается сокращать кетчуп, потому что будет несколько раз, когда данный отчет необходимо запускать для данного члена (после запуска значение больше недействительно/ полезный).

Прежде чем показать следующий дизайн таблицы-кандидата, несколько слов о том, когда эти отчеты могут быть созданы (сгенерированы и отправлены по электронной почте): конфигуратор может настроить их для запуска в определенный день каждого месяца (1-е, 10-е, 17-е число). , что угодно) ИЛИ в соответствии с шаблоном, то есть они могут быть установлены как «первый вторник каждого месяца», или «последняя пятница каждого месяца», или «первый понедельник каждой недели» (IOW, каждый понедельник). Итак, я придумал это:

ReportScheduler
---------------
AutoID int
MemberID VarChar(6)
ReportID int
DayOfMonth int
PatternOrdinal VarChar(6) // First, Second, Third, Fourth, or Last
PatternDOW VarChar(9) // Monday, ... Sunday
PatternInterval VarChar(5) // Week, Month

... но затем понял, что это также не имеет особого смысла, потому что код должен будет запускаться, чтобы вычислить, была ли достигнута или превышена какая-либо дата, которая соответствует комбинации полей DayOfMonth или Pattern, каждый раз, когда опрашивается БД . И тогда что помешает этому срабатывать навсегда после этого?

Итак, я думаю, что мне нужно объединить эти идеи, но вместо RunWhen вызовите поле DateTime NextExecution и обновите его каждый раз, когда отчет создается для данного участника:

ReportScheduler
---------------
AutoID int
MemberID VarChar(6)
ReportID int
NextExecution DateTime
DayOfMonth int
PatternOrdinal VarChar(6) // First, Second, Third, Fourth, or Last
PatternDOW VarChar(9) // Monday, ... Sunday
PatternInterval VarChar(5) // Week, Month

Когда время NextExecution достигнуто или превышено, Служба генерирует/отправляет отчет по электронной почте. Затем он вычисляет, когда должно произойти следующее выполнение (на основе полей DayOfMonth или Pattern*), и обновляет поле NextExecution этим значением.

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


person B. Clay Shannon    schedule 11.02.2016    source источник


Ответы (1)


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

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

person Tom H    schedule 11.02.2016