Pregunta de diseño: ¿cómo diseñaría un sistema de eventos recurrentes?


44

Si le pidieron que construyera un sistema de programación de eventos que admitiera eventos recurrentes, ¿cómo lo haría? ¿Cómo manejas cuando se elimina un evento recurrente? ¿Cómo puedes ver cuándo ocurrirán los eventos futuros?

es decir, al crear un evento, puede elegir "repetición diaria" (o semanal, anual, etc.).

Un diseño por respuesta, por favor. Estoy acostumbrado a Ruby/Rails, pero usa lo que quieras para expresar el diseño.

Me lo preguntaron en una entrevista y no pude encontrar una buena respuesta que me gustara.

Nota: era already asked/answered here. Pero yo tenía la esperanza de obtener algunos detalles más prácticos, como se detalla a continuación:

  • Si era necesario para poder comentar o añadir datos a una sola instancia del evento recurrente de otro modo ¿Cómo funcionaría eso?
  • ¿Cómo funcionarían los cambios y eliminaciones de eventos?
  • ¿Cómo se calcula cuándo suceden los eventos futuros?
+1

Me encanta esta pregunta, pero sospecho que se cerrará. 28 oct. 142014-10-28 20:23:43

  0

@ joe-van-dyk Hola, tengo el mismo problema, ¿pueden agregar sus recomendaciones y vincular su solución de git en la parte de respuesta? Creo que has resuelto este problema. Soy interesante en el modelo de datos en general. Gracias 16 may. 172017-05-16 18:42:48

0

Al guardar el evento me gustaría guardar la programación a una tienda (vamos a llamarlo "Horarios" y me gustaría calcular cuando el evento era para disparar la próxima vez y guardar eso también, por ejemplo, en "Eventos". entonces me vería en "Eventos " y averiguar cuando el próximo evento iba a tener lugar e ir a dormir hasta entonces.

cuando la aplicación se "despierta" sería calcular cuándo el evento debería tener lugar nuevamente, almacénelo en "Eventos" nuevamente y luego realice el evento.

Repita.

Si se crea un evento mientras duerme, la suspensión se interrumpe y se vuelve a calcular.

Si la aplicación está comenzando o recuperándose de un evento de suspensión o similar, marque "Eventos" para eventos pasados ​​y actúe en consecuencia (dependiendo de lo que quiera hacer con eventos perdidos).

Algo como esto sería flexible y no tomaría ciclos de CPU innecesarios.

  0

¿Podría mirar en el futuro y ver cuándo serían los próximos eventos? 23 sep. 082008-09-23 21:03:25


2

He tenido que hacer esto antes cuando gestionaba la base de datos al final del proyecto. Solicité que cada evento se almacenara como eventos separados. Esto le permite eliminar solo una ocurrencia o puede mover un lapso. Es mucho más fácil eliminar múltiples que tratar de modificar una única ocurrencia y convertirla en dos. Luego pudimos hacer otra tabla que simplemente tenía un ID recurrente que contenía la información de la recurrencia.


0

De la parte superior de la cabeza (después de revisar un par de cosas mientras se escribe/pensamiento):

determinar la recurrencia resolución mínima necesaria; esa es la frecuencia con la que se ejecuta la aplicación. Tal vez sea a diario, tal vez cada cinco minutos.

Para cada evento recurrente, almacene el tiempo de ejecución más reciente, el intervalo de ejecución y otros extras como el tiempo de caducidad, si es conveniente.

Cada vez que se ejecuta la aplicación, comprueba todos los eventos, comparando (today/now + recurrenceResolution) con (recentRunTime + runInterval) y si coinciden, desencadena el evento.


2

@Joe Van Dyk preguntó: "¿Podrías mirar en el futuro y ver cuándo serían los próximos eventos?"

Si quería ver/pantalla los próximos n ocurrencias de un evento que tendrían que sea a) puede calcular de antemano y se almacena en algún lugar o b) se calculará sobre la marcha y desplegado. Esto sería lo mismo para cualquier marco nocturno.

La desventaja de a) es que tienes que ponerle un límite en alguna parte y luego tienes que usar b). Más fácil de usar b) para empezar.

El sistema de programación no necesita esta información, solo necesita saber cuándo es el siguiente evento.

  0

O mezcle los dos. Calcule según demanda (b), luego almacene los resultados para referencia posterior (a). 24 sep. 082008-09-24 06:34:28


0

Cuando escribí una aplicación de calendario para mí murmuró años atrás, básicamente robé el mecanismo de programación de cron y lo usé para eventos recurrentes. por ejemplo, algo que tenga lugar el segundo sábado de cada mes, excepto enero, incluiría la instrucción "repeat = * 2-12 8-14 6" (cada año, meses 2-12, la segunda semana se desarrolla del 8 al 14, y 6 para el sábado porque utilicé la numeración basada en 0 para los días de la semana).

Si bien esto hace que sea bastante fácil determinar si el evento ocurre en cualquier fecha dada, no es capaz de responder a "cada N días" y también es menos intuitivo para usuarios que no son expertos en Unix.

Para tratar con datos únicos para instancias de eventos individuales y remoción/reprogramación, solo realicé un seguimiento de hasta qué punto los eventos se habían calculado y almacenado en la base de datos, donde podrían modificarse, moverse o eliminado sin afectar la información original del evento recurrente. Cuando se agregaba un nuevo evento recurrente, todas las instancias se calculaban inmediatamente hasta la fecha de "último cálculo" existente.

No pretendo que esta sea la mejor manera de hacerlo, pero es una forma, y una que funciona bastante bien dentro de las limitaciones que mencioné anteriormente.


0

Si tiene un evento recurrente simple, como diario, semanal o un par de días a la semana, ¿cuál es el problema con el uso de buildt en scheduler/cron/at functionallity? ¿Crea una aplicación ejecutable/consola y establece cuándo ejecutarla? Sin calendario complicado, evento o administración de tiempo.

:)

// W

+1

no funciona para una aplicación web 06 oct. 082008-10-06 01:34:53


9

empecé por la aplicación de algunas expresión temporal como outlined by Martin Fowler. Esto se ocupa de averiguar cuándo debería ocurrir realmente un elemento programado. Es una forma muy elegante de hacerlo. Con lo que terminé fue solo una acumulación de lo que está en el artículo.

El siguiente problema fue descubrir cómo en el mundo para almacenar las expresiones. El otro problema es cuando lees la expresión, ¿cómo encajan en una interfaz de usuario no tan dinámica?Se habló de simplemente serializar las expresiones en un BLOB, pero sería difícil caminar por el árbol de expresiones para saber qué significaba.

La solución (en mi caso) es almacenar parámetros que se ajusten al número limitado de casos soportados por la Interfaz de usuario, y desde allí, usar esa información para generar Expresiones Temporales sobre la marcha (podría serializarse cuando se creó para optimización) Entonces, la clase Schedule termina teniendo varios parámetros como offset, fecha de inicio, fecha de finalización, día de la semana, y así sucesivamente ... y a partir de eso puede generar expresiones temporales para hacer el trabajo duro.

En cuanto a tener instancias de las tareas, hay un 'servicio' que genera tareas por N días. Como esto es una integración a un sistema existente y todas las instancias son necesarias, esto tiene sentido. Sin embargo, una API como esta se puede usar fácilmente para proyectar las recurrencias sin almacenar todas las instancias.