0

First memory leak I needed to debug on Nodejs/JS, so some newbie questions here. I wanted to get some advice on code design..specifically:

I have a connection a mysql database, and I leave it open as a global variable, so that I don't have to establish connection and tear down. I have frequent access requests. I have connection to google services, and similarly, establish a connection object at global level so that I don't have to re-connect each time and delay users. For 1&2, above, are there any negative concerns I should have on memory leaks? (vs. having them invoked and torn down within a function scope)

snippets:

import  mysql from 'mysql';
const connection = mysql.createConnection({
    host: 'localhost',
    user: 'xxxx',
    password: 'xxx',
    database: 'xxx' ,
    charset: 'utf8mb4'
});

 connection.connect((err) => {
    if (err) throw err;
    console.log('Connected!');
});
...
export {connection as default};

and here is the other:

import config from './config.json';
import Discord from 'discord.js';

//discord bot
const bot = new Discord.Client();

// We also need to make sure we're attaching the config to the CLIENT so it's accessible everywhere!
bot.config = config;
bot.commands = new Discord.Collection();
bot.aliases = new  Discord.Collection();
bot.help = new Discord.Collection();

bot.login(config.token);

export default bot;

and the google connection

// Imports the Google Cloud client library
import { TranslationServiceClient } from '@google-cloud/translate';

// instantiate an instance of a connection to google translate API
const translationClient = new TranslationServiceClient();

Wondering if there is a different/better way to approach this?

G-Force
  • 345
  • 3
  • 10

2 Answers2

1

IMO its better to initialize connection like this, because at a time you export your connection, it is not established, which might cause different problems.

const createMsqlConnection = () => {
  return new Promise((resolve, reject) => {
  const connection = mysql.createConnection({
      host: 'localhost',
      user: 'xxxx',
      password: 'xxx',
      database: 'xxx' ,
      charset: 'utf8mb4'
  });

   connection.connect((err) => {
      if (err) reject(err);
      console.log('connected')
      resolve(connection);
  });
  })
}

const start = async () => {
   const connection = await createMsqlConnection()
   // use connection here...
}

start.then()

So in other words instead of exporting connection, its better to export the Promise, which creates it

Nikita Mazur
  • 1,602
  • 1
  • 5
  • 14
  • thanks for the feedback. Yes I agree the promise would ensure initialization doesn't have a timing issue with callers of that exported object. The object would still need to be exported though (via the promise resolution). It's good improvement suggestion, but doesn't really answer my question about memory management. – G-Force Jul 08 '21 at 16:20
0

it turns out I didn't have a memory leak. After performing a lot of tracing, I determined the GC is indeed collecting and I didn't have any growing chunks.

What I learned, also after googling other issues, is that I simply was getting more traffic concurrently, which was exceeding my memory available on peak thread concurrent hits.

I grew my VM's memory, and it didn't help initially, which helped me understand that it was a setting issue. I needed to grow the size of node memory available, and this solved the problem. Been running for days now without growth.

Dharman
  • 30,962
  • 25
  • 85
  • 135
G-Force
  • 345
  • 3
  • 10