nuestra aplicación de back-end NodeJS tiene más de 200 000 usuarios y cada semana hacemos algunos controles/cálculos basados en los usuarios. El funcionamiento es similar a este:
const users = await dbService.user.findMany({}); // Array of 200K+ users for (let index = 0; index < users.length; index++) { const user = users[index]; const result = await checkUserSubscriptions({ id: user.id }); // do operations according to result, mostly updateUser in database. }Durante el proceso, la mayoría de las demás solicitudes no se ejecutan o se esperan hasta que finaliza esta operación. Por ejemplo, cuando un usuario intenta iniciar sesión, espera hasta que finaliza este bucle o sufre un gran retraso. Debido a que esta operación no necesita ser instantánea y puede demorarse o ser lenta, necesito usar algo más que no bloquee nuestra cola principal. ¿Qué puedo hacer para asegurar esto?
Lo que intenta hacer es como un trabajo en segundo plano y no debería estar en el mismo proceso de su servicio web. El uso de memoria del procesamiento de 200 000 usuarios tendrá un impacto en el rendimiento de su servicio web. La arquitectura de Nodejs es de subproceso único y no importa si intenta ejecutar tareas asíncronas de 200K, el rendimiento de su servicio web se verá afectado.
Puede ver worker_threads , útil para realizar operaciones de JavaScript con uso intensivo de CPU. Hay otros paquetes que pueden ayudarte. Puedes echar un vistazo al toro
Es una mala práctica colocar un await dentro de un bucle porque hace que el código sea sincrónico y se pierde la capacidad de paralelismo: cada iteración del bucle tiene que esperar a que se complete la anterior antes de activarse.
Deberías usar Promise.all :
const users = await dbService.user.findMany({}); // Array of 200K+ users const results = await Promise.all(users.map((user) => { return checkUserSubscriptions({ id: user.id }); })) // results is an array of returned values from checkUserSubscriptions