design - personalized - Pregunta de diseño: ¿cómo diseñarías un sistema de eventos recurrentes?
search design canva (7)
Si tuviera la tarea de crear 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 "repetir diariamente" (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 respuesta realmente buena que me gustara.
Nota: ya fue preguntado / respondido aquí. Pero esperaba obtener algunos detalles más prácticos, como se detalla a continuación:
- Si fuera necesario poder comentar o agregar datos a una sola instancia del evento recurrente, ¿cómo funcionaría?
- ¿Cómo funcionarían los cambios y eliminaciones de eventos?
- ¿Cómo se calcula cuándo suceden los eventos futuros?
Cuando escribí una aplicación de calendario para mí misma hace años, 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 una fecha determinada, no es capaz de manejar la repetición de "cada N días" y también es bastante menos intuitivo para los usuarios que no son expertos en Unix.
Para tratar con datos únicos para instancias de eventos individuales y eliminación / reprogramación, simplemente hice un seguimiento de hasta qué punto los eventos se habían calculado y almacenado los eventos resultantes en la base de datos, donde podrían modificarse, moverse o eliminarse sin afectar el 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 manera que funciona bastante bien dentro de las limitaciones que mencioné anteriormente.
Cuando guardaba el evento, guardaba el horario en una tienda (llamémoslo " Horarios " y yo calculaba cuándo el evento debía disparar la próxima vez y también lo guardaba, por ejemplo en " Eventos ". mira en " Eventos " y averigua cuándo tendrá lugar el próximo evento y duerme hasta entonces.
Cuando la aplicación "se despierta", se calcularía cuándo el evento debería tener lugar nuevamente, almacenar esto en " Eventos " nuevamente y luego realizar el evento.
Repetir.
Si se crea un evento mientras duerme, el sueño se interrumpe y se vuelve a calcular.
Si la aplicación está comenzando o recuperándose de un evento de suspensión o similar, verifique " Eventos " para eventos pasados y actúe en consecuencia (dependiendo de lo que quiera hacer con los eventos perdidos).
Algo como esto sería flexible y no tomaría ciclos de CPU innecesarios.
Empecé implementando una expresión temporal como la describe 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 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 que admitirá la Interfaz de usuario, y a partir de ahí, usar esa información para generar Expresiones Temporales sobre la marcha (podría serializarse cuando se crea para la 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.
Fuera de mi cabeza (después de revisar un par de cosas mientras escribo / pienso):
Determine la mínima resolución de recurrencia 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 elementos, 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, activa el evento.
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.
Si tiene un evento recurrente simple, como diario, semanal o un par de días a la semana, ¿qué ocurre con el uso de buildt en planificador / cron / en functionallity? ¿Crea una aplicación ejecutable / consola y establece cuándo ejecutarla? Sin calendario complicado, evento o administración de tiempo.
:)
// W
@Joe Van Dyk preguntó: "¿Podrías mirar en el futuro y ver cuándo serían los próximos eventos?"
Si quisiera ver / mostrar las siguientes n ocurrencias de un evento, éstas tendrían que a ) calcularse con anticipación y almacenarse en algún lugar o b) calcularse sobre la marcha y mostrarse. 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 será el próximo evento.