Comment s'utilise en pratique response.resume() ?

Et éviter des fuites de données sur un bot

a marqué ce sujet comme résolu.

Bonjour ! :)

J’ai créé un bot Discord dont je constate une croissance régulière de la mémoire utilisée. Toutes les 5 minutes environ, le bot utilise 0,2 Mb de mémoire en plus. Je suspecte une fuite de mémoire, et j’ignore où elle se situe dans mon code. Si vous pouviez y jeter un œil et me donner une piste, ce serait top !

/**
  *     This bot fetches a remote API and
  *     does some stuff with the collected data.
  */


const https = require('https');
const {Client, Intents} = require('discord.js');

const client = new Client({intents: [
    Intents.FLAGS.GUILD_MESSAGES,
    Intents.FLAGS.GUILDS,
    Intents.FLAGS.GUILD_INTEGRATIONS,
    Intents.FLAGS.GUILD_WEBHOOKS
]});

client.once('ready', () => {
    console.log('Bot connecté !');
    fetchAPI();
});





async function fetchAPI() {

    https.get('https://api.example.com/?req=someRequest', async res => {

        if (res.statusCode !== 200) {
            console.log(`Request Failed With Code: ${res.statusCode}`);
            res.resume();

            // Attends 30 sec puis rééssaye
            await sleep(30000);
            fetchAPI();
            return;
        }


        // Reçois les données
        let rawData = '';
        res.setEncoding('utf8');
        res.on('data', chunk => rawData += chunk);


        res.on('end', async () => {
            // Ici on utilise rawData, on traite les données
            // Doit-on faire un appel à res.resume() ici à la fin ?
        });
    }).on('error', e => {console.log(`Error: ${e.message}`);});


    // On attend 5 min avant la prochaine requête
    await sleep(5000 * 60);
    fetchAPI();
}



function sleep(ms) {
    return new Promise(res => setTimeout(res, ms));
}

client.login('BOT TOKEN');

J’ai pensé qu’il manque peut-être un res.resume() à la ligne 49 environ, mais en essayant cette solution, elle ne fonctionne pas. De plus, je ne comprends pas ce que fait cet appel, de ce que j’ai compris, elle force le flux de données à continuer d’émettre, ce qui potentiellement peut libérer de la mémoire lorsque le flux n’est pas consommé. Dans mon code, j’ai l’impression que ce flux est consommé, mais je me trompe peut-être.

Peut-être que la fuite de mémoire vient d’ailleurs, auriez-vous des idées ?
PS : le bot ne fait rien d’autre sur le côté, à part faire quelques calculs avec les données collectées et les envoyer dans un salon Discord.

Merci d’avance ^^

Salut,

Un stream c’est plus souvent utilisé pour lire des données binaires ou linéaires, ce qui n’est pas vraiment le cas du JSON (je suppose que c’est ce que tu essaies de récupérer).

Dans ton code je vois déjà deux risques potentiels :

  1. ligne 56 tu n’attends pas le retour d’une requête avant de lancer le timer pour la suivante. Si une requête prend plus de temps que prévu, tu auras donc un décalage voire des résultats qui n’arrivent pas dans le bon ordre.
  2. Ligne 36 tu lances une nouvelle requête comme il faut (après avoir eu le retour de la requête en cours), mais elle va se cumuler à celle de la ligne 56. Tu lances donc deux nouvelles requêtes à chaque fois que tu en fais une, d’où probablement ta fuite mémoire.

Merci pour la réponse !

Salut,

Un stream c’est plus souvent utilisé pour lire des données binaires ou linéaires, ce qui n’est pas vraiment le cas du JSON (je suppose que c’est ce que tu essaies de récupérer).

Effectivement, je récupère du JSON. Connais-tu un moyen plus efficace ou plus simple de récupérer ce JSON ? Mon code est inspiré de cet exemple trouvé dans la doc. Peut-être que l’exemple est mal choisis ?

Dans ton code je vois déjà deux risques potentiels :

  1. ligne 56 tu n’attends pas le retour d’une requête avant de lancer le timer pour la suivante. Si une requête prend plus de temps que prévu, tu auras donc un décalage voire des résultats qui n’arrivent pas dans le bon ordre.
  2. Ligne 36 tu lances une nouvelle requête comme il faut (après avoir eu le retour de la requête en cours), mais elle va se cumuler à celle de la ligne 56. Tu lances donc deux nouvelles requêtes à chaque fois que tu en fais une, d’où probablement ta fuite mémoire.
viki53

Je vais essayer de réparer ça, merci :)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte