Question de conception: Comment concevez-vous un système d’événements récurrents?

Si vous deviez créer un système de planification d’événements prenant en charge les événements récurrents, comment le feriez-vous? Comment gérez-vous lorsqu’un événement récurrent est supprimé? Comment pourriez-vous voir les événements futurs?

Par exemple, lors de la création d’un événement, vous pouvez choisir “répétition quotidienne” (ou hebdomadaire, annuel, etc.).

Un design par réponse s’il vous plaît. Je suis habitué à Ruby / Rails, mais utilisez ce que vous voulez pour exprimer le design.

On m’a demandé cela lors d’une interview, et je n’ai pas pu trouver une réponse vraiment satisfaisante.

Note: a déjà été demandé / répondu ici. Mais j’espérais obtenir des détails plus pratiques, comme détaillé ci-dessous:

  • S’il était nécessaire de pouvoir commenter ou append des données à une seule instance de l’événement récurrent, comment cela fonctionnerait-il?
  • Comment fonctionneraient les changements d’événements et les suppressions?
  • Comment calculez-vous lorsque des événements futurs se produisent?

J’ai commencé par mettre en œuvre une expression temporelle telle que décrite par Martin Fowler . Cela permet de déterminer à quel moment un élément programmé doit réellement se produire. C’est une manière très élégante de le faire. Ce avec quoi je me suis retrouvé était juste une accumulation sur ce qui est dans l’article.

Le problème suivant consistait à déterminer comment stocker les expressions dans le monde. L’autre problème est que lorsque vous lisez l’expression, comment sont-ils adaptés à une interface utilisateur moins dynamic? On parlait de simplement sérialiser les expressions dans un BLOB, mais il serait difficile de parcourir l’arbre d’expression pour savoir ce qu’il voulait dire.

La solution (dans mon cas) consiste à stocker des parameters correspondant au nombre limité de cas pris en charge par l’interface utilisateur. À partir de là, utilisez ces informations pour générer les expressions temporelles à la volée (susceptibles d’être sérialisées pour l’optimisation). Ainsi, la classe Schedule finit par avoir plusieurs parameters comme offset, date de début, date de fin, jour de la semaine, etc. et à partir de là, vous pouvez générer les expressions temporelles pour faire le travail difficile.

En ce qui concerne les instances des tâches, il existe un “service” qui génère des tâches pour N jours. Comme il s’agit d’une intégration à un système existant et que toutes les instances sont nécessaires, cela a du sens. Cependant, une API comme celle-ci peut facilement être utilisée pour projeter les récurrences sans stocker toutes les instances.

Je devais le faire avant de gérer la fin de la firebase database du projet. J’ai demandé que chaque événement soit enregistré en tant qu’événements séparés. Cela vous permet de supprimer une seule occurrence ou de déplacer une plage. Il est beaucoup plus facile de supprimer des multiples que d’essayer de modifier une seule occurrence et de la transformer en deux. Nous avons ensuite été en mesure de créer une autre table contenant simplement un recurrenceID contenant les informations sur la récurrence.

@Joe Van Dyk a demandé: “Pourriez-vous regarder dans le futur et voir quand les événements à venir seront?”

Si vous vouliez voir / afficher les n prochaines occurrences d’un événement, elles devraient soit: a) être calculées à l’avance et stockées quelque part ou b) être calculées à la volée et affichées. Ce serait la même chose pour tout cadre du soir.

L’inconvénient avec a) est qu’il faut y mettre une limite quelque part et après, il faut utiliser b). Plus facile juste d’utiliser b) pour commencer.

Le système de planification n’a pas besoin de cette information, il a juste besoin de savoir quand le prochain événement est.

Lors de la sauvegarde de l’événement, je sauvegardais le planning dans un magasin (appelons-le ” Schedules ” et je calculerais à quel moment l’événement devait se déclencher la prochaine fois et enregistrez-le également, par exemple dans ” Events “). regardez dans ” Événements ” et déterminez quand le prochain événement devait avoir lieu et dormez jusque-là.

Lorsque l’application “se réveille”, elle calcule à quel moment l’événement doit avoir lieu, stockez-le à nouveau dans ” Evénements “, puis effectuez l’événement.

Répéter.

Si un événement est créé en dormant, le sumil est interrompu et recalculé.

Si l’application démarre ou se remet d’un événement de veille ou similaire, cochez ” Événements ” pour les événements passés et agissez en conséquence (en fonction de ce que vous voulez faire des événements manqués).

Quelque chose comme cela serait flexible et ne prendrait pas de cycles de CPU inutiles.

Au sumt de ma tête (après avoir révisé deux choses en tapant / réfléchissant):

Déterminer la résolution de récurrence minimale nécessaire; c’est la fréquence d’exécution de l’application. Peut-être que c’est tous les jours, peut-être toutes les cinq minutes.

Pour chaque événement récurrent, stockez le temps d’exécution le plus récent, l’intervalle d’exécution et les autres avantages tels que le délai d’expiration, si cela est souhaitable.

Chaque fois que l’application s’exécute, elle vérifie tous les événements en comparant (aujourd’hui / maintenant + recurrenceResolution) à (recentRunTime + runInterval) et s’ils coïncident, déclenche l’événement.

Lorsque j’ai écrit une application de calendrier pour moi quelques années auparavant, j’ai simplement volé le mécanisme de planification de cron et je l’ai utilisé pour les événements récurrents. Par exemple, quelque chose qui a lieu le deuxième samedi de chaque mois, à l’exception de janvier, inclurait l’instruction “repeat = * 2-12 8-14 6” (chaque année, mois 2-12, la 2ème semaine du 8 au 14, et 6 pour samedi car j’ai utilisé une numérotation basée sur 0 pour les jours de la semaine).

Bien qu’il soit assez facile de déterminer si l’événement se produit à une date donnée, il n’est pas capable de gérer une récurrence de “tous les N jours” et est plutôt peu intuitif pour les utilisateurs peu avertis.

Pour gérer des données uniques pour des instances d’événements et des opérations de suppression / reprogrammation individuelles, je me suis contenté de savoir dans quelle mesure les événements avaient été calculés et stockés dans la firebase database, puis modifiés, déplacés ou supprimés. informations sur les événements récurrents d’origine. Lorsqu’un nouvel événement récurrent était ajouté, toutes les instances étaient immédiatement calculées jusqu’à la date de “dernier calcul” existante.

Je ne prétends pas que c’est la meilleure façon de le faire, mais c’est un moyen, et c’est un moyen qui fonctionne assez bien dans les limites que j’ai déjà mentionnées.

Si vous avez un événement récurrent simple, tel que quotidien, hebdomadaire ou quelques jours par semaine, quel est le problème avec l’utilisation de buildt dans scheduler / cron / at functionallity? Créer une application exécutable / console et configurer quand l’exécuter? Pas de gestion compliquée du calendrier, des événements ou du temps.

🙂

// W