In TypeScript, I created a class that utilizes a websocket to emit pre-fetched data from mongoose based on certain parameters.
PLEASE NOTE: The code provided here is for demonstration purposes only and not the actual implementation. It has been simplified for easier understanding
import { Server as SocketServer } from 'socket.io';
import { Animal, AnimalModel } from './animal.model.ts';
// ^^^^^^^ this consists of basic properties interface and a mongoose schema
export class Stream {
private io: SocketServer;
private breed: string;
private animals: Array<Animal>;
constructor(
io: SocketServer,
breed: string
) {
this.io = io;
this.breed = breed;
this.fetch(); // initial fetch
setInterval(() => this.emit(), 1000); // emit every second
setInterval(() => this.fetch(), 1000); // fetch it every second for updates
// ^^^ when I comment out this line, memory leakage seems to be resolved
}
/**
* Fetch the list of animals based on the specified breed
*/
private async fetch(): Promise<void> {
this.animals = await AnimalModel.find({breed: this.breed}).limit(20).exec(); // each fetch retrieves around 100kb
}
/**
* Emit the list of animals to subscribers of the breed
*/
private emit(): void {
this.io.in(this.breed).emit("animals", JSON.stringify(this.animals))
}
}
The generation of these animals is done like this:
import { AnimalModel } from './animal.model.ts';
const socket = makeSocket(); // function to create a new socket.io instance
const initialize = async () => {
// About 25 animals
const animalsList = await AnimalModel.find().exec();
animalsList.forEach(animal => {
new Stream(socket, animal.breed); // creates a new stream for each animal breed with a reference to the socket
});
};
initialize();
The issue arises when each fetch operation (per breed) consumes about 100kb, resulting in approximately 2.5MB being added to the memory heap every second. By excluding the fetch operation, further increase in memory usage is prevented. It appears that the fetch function is not releasing resources properly.
I have spent hours attempting various solutions, including using Chrome NodeJS debug tool and experimenting with different functions, but no success so far. Can anyone provide assistance or suggest alternative code that avoids memory leaks?
PS: I have Heap snapshots available if needed