Estoy desarrollando un sistema de recordatorio por correo electrónico para hacer ping a los usuarios 24, 8, 3 y 1 hora antes de la fecha de vencimiento de una tarea.
Tengo un servidor que se ejecuta en Node.js. Mi primera idea fue establecer cuatro setTimeout() separados cada vez que a un usuario se le asigna una tarea. Sin embargo, asumo que tener cientos de setTimeout() inactivos en un servidor no sería lo mejor en términos de rendimiento.
Como tal, ¿sería mejor encuestar las tareas incompletas cada cinco minutos y enviar recordatorios a los usuarios que tienen tareas con fechas de entrega próximas? La desventaja aquí es que estaría leyendo una colección completa de MongoDB cada cinco minutos.
Nodejs es muy eficiente con muchos temporizadores. Puede tener fácilmente decenas de miles de temporizadores sin ramificaciones significativas. Utiliza una lista ordenada y enlazada que toma solo una pequeña cantidad de tiempo para insertar un nuevo temporizador y no cuesta nada una vez que se inserta.
En el ciclo de eventos, solo se compara regularmente el siguiente temporizador que se disparará al comienzo de la lista. Cuando se dispara, se elimina del frente de la lista enlazada y el siguiente temporizador de la lista ahora está a la cabeza. Debido a que es una lista enlazada, el tiempo para activar un temporizador y eliminarlo del inicio de la lista enlazada es independiente de la longitud de la lista (por ejemplo, no es una matriz que deba copiarse).
Por lo tanto, para su aplicación específica, es mucho, mucho más importante ser eficiente con su base de datos (tan pocas solicitudes como sea posible) que minimizar la cantidad de temporizadores. Por lo tanto, cualquier diseño/implementación del temporizador que optimice la carga de su base de datos es lo que yo recomendaría.
Para su información, si desea recordarle a un usuario 4 veces acerca de una tarea vencida que se aproxima, solo puede tener un temporizador en vivo a la vez por tarea. Configure el primer temporizador para que se active, luego, cuando se active para notificar, haga un pequeño cálculo de tiempo en la fecha/hora de vencimiento que guardó previamente y vea cuándo configurar el próximo temporizador. Eso lo dejaría con solo un temporizador por tarea en lugar de cuatro.
Pero, el punto principal aquí sigue siendo que primero debe optimizar el diseño para un uso eficiente de la base de datos.
Y, los temporizadores no son persistentes, por lo que si su servidor se reinicia, necesita un mecanismo para recrear los temporizadores apropiados al iniciar el servidor (probablemente una consulta de la base de datos que le proporcione las tareas pendientes dentro de un tiempo determinado).