簡體   English   中英

Memory 在承諾的情況下泄漏

[英]Memory leak in while with promises

我有一個nodejs 集群,它的主節點處理工作周期(在 while 循環中)並監聽工作消息以在周期中進行。 (在我的代碼中 index.js 不會在 setInterval 上發送消息,而是在其他類型的事件上發送消息,我在這里簡化了代碼以了解問題的本質)

服務器.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')
}

索引.js

const ClusterMessages = require('cluster-messages');
const messages = new ClusterMessages();

setInterval(() => {
    messages.send('enough');
}, 1000);

該代碼工作正常(因此,在本示例和我的代碼中),但似乎存在 memory 泄漏,正如您可以從該代碼的 output 中理解的那樣:

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

我嘗試了幾件事,比如交換新的 Promise 和 messages.on(),在 promise 的回調中添加返回,但我不知道這里發生了什么。 有任何想法嗎?

每次調用enough()都會為messages上的enough事件安裝另一個偵聽器。 它們永遠不會被刪除,泄漏 memory(並導致每個事件的日志數量增加)。 相反,使用once方法安裝監聽器:

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

甚至更簡單,使用once

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

在您的特定示例中,我建議不要使用承諾來處理事件。 您甚至可能會錯過在刪除和重新附加偵聽器時觸發的事件。 寫吧

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

如果由於某種原因您需要一個可以中斷或await其他事情的循環,我會推薦一個異步迭代器,使用on構建:

const { once } = require('events');
(async () => {
    let cycle = 0
    for await (const _ of on(messages, 'enough')) {
        console.log(cycle);
        cycle++;
    }
})();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM