Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

99
Vistas
Fuga de memoria con promesas

Tengo un clúster de nodejs con un principal que maneja los ciclos de los trabajadores (en el ciclo while) y que escucha los mensajes de los trabajadores para progresar en el ciclo. (En mi código, index.js no envía mensajes en setInterval sino en otro tipo de evento, aquí he simplificado el código para obtener la esencia del problema)

Servidor.js

 var cluster = require('cluster'); const ClusterMessages = require('cluster-messages'); const messages = new ClusterMessages(); if (cluster.isMaster){ let worker = cluster.fork() console.log(cluster); (async ()=>{ let cycle = 0 while(true){ console.log(cycle); cycle ++ await Promise.all([ enough(), ]) } function enough () { return new Promise(resolve => { messages.on('enough', () => { console.log('enough'); resolve() }); }); }})() } else { require('./index.js') }

Índice.js

 const ClusterMessages = require('cluster-messages'); const messages = new ClusterMessages(); setInterval(() => { messages.send('enough'); }, 1000);

El código funciona bien (como tal, en este ejemplo y en mi código), pero parece haber una pérdida de memoria, como puede comprender a partir del resultado de este código:

 0 enough 1 enough enough 2 enough enough enough 3 enough enough enough enough...

Intenté varias cosas, como intercambiar una nueva promesa y mensajes. on(), agregar un retorno en la devolución de llamada de la promesa, pero no tengo idea de lo que está sucediendo aquí. ¿Algunas ideas?


La solución es crear otro evento que pueda activarse una vez contrario al 'escucha de eventos' del paquete de mensajes de clúster.

Servidor.js

 if (cluster.isMaster){ let worker = cluster.fork() console.log(cluster); // Importing events const EventEmitter = require('events'); const eventEmitter = new EventEmitter(); messages.on('enough', () => { eventEmitter.emit('event'); }); (async ()=>{let cycle = 0 while(true){ console.log(cycle); cycle ++ await Promise.all([ enough(), ]) } function enough () { return new Promise(resolve => { eventEmitter.once('event', () => { console.log('event'); resolve() }); }); }})() } else { require('./index.js') }

Índice.js

 const ClusterMessages = require('cluster-messages'); const messages = new ClusterMessages(); setInterval(() => { messages.send('enough'); }, 1000);
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Cada llamada enough() instala otro oyente para el evento enough en los messages . Nunca se eliminan, lo que provoca una fuga de memoria (lo que genera un número cada vez mayor de registros por evento). En su lugar, utilice el método de once para instalar el oyente:

 function enough () { return new Promise(resolve => { messages.once('enough', () => { // ^^^^ console.log('enough'); resolve(); }); }); }

O incluso más simple, usando once :

 const { once } = require('events'); function enough() { return once(messages, 'enough'); }

En su ejemplo particular, recomendaría no usar promesas para manejar los eventos. Incluso puede perder eventos que se activan mientras elimina y vuelve a conectar un oyente. Solo escribe

 let cycle = 0 messages.on('enough', () => { console.log(cycle); cycle++; });

Si por alguna razón necesita un bucle del que pueda romper o await otras cosas, recomendaría un iterador asíncrono, construido on :

 const { once } = require('events'); (async () => { let cycle = 0 for await (const _ of on(messages, 'enough')) { console.log(cycle); cycle++; } })();
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda