Heap memory leak pptxgenjs

272 views Asked by At

Currently I am creating a ppt file using pptxgenjs and export it. the pptexporter file contain many other function to get assets and string etc. but there is always memory leak when I use large assets such as images and videos size bigger than container mem_limit which will kills the container. I did heap dump before and after generating the ppt file there is a big difference. but somehow after the response is sent the heap memory is still very large. Is it because I am not streaming data properly ? But it seems pptxgenjs is taking care of the assets while building the ppt.

If no large image assets or video are used the heap is stable at around 51mb. But if i use a asset or many assets total size of 300mb, docker stats shows the memory jumps to 1.6g at one point.

comparison between dump after response sent and before generate ppt file stream: enter image description here

part of pptExporter.js:

export default async (project) => {
    const pptx = await initPresentation(project);
    slide.addText(project.properties.courseTitle.properties.value.data, slideHelpers.mainTitleOptions);
    await createLessons(pptx, project);
    slide.addText(project.properties.courseAudience.properties.value.data, slideHelpers.mainAudienceOptions);

    return pptx.stream().then(data => {
        return new Buffer(data, "base64");
    });
};

getCoursePpt.js:

import getPptFile from './pptExporter';
export default async (project, fileName, credentials) => {
    heapdump.writeSnapshot('/' + Date.now() + '.heapsnapshot');
    heapdump.writeSnapshot(function (err, filename) {
        console.log('dump1 written to', filename);
    });
    const pptFile = await getPptFile(project);
    heapdump.writeSnapshot('/' + Date.now() + '.heapsnapshot');
    heapdump.writeSnapshot(function (err, filename) {
        console.log('dump2 written to', filename);
    });
    const s3 = new AWS.S3({
        credentials: new AWS.Credentials({
            accessKeyId: credentials.accessKey,
            secretAccessKey: credentials.secretAccess
        })
    });
    const params = {
        Key: `${fileName}.pptx`,
        Bucket: credentials.name,
        Body: pptFile
    };

    const uploadPromise = () => new Promise((resolve, reject) => {
        s3.upload(params, (error, data) => {
            if (error) {
                reject(error);
            } else {
                resolve(data.Location);
            }
        });
    });
    let data;
    try {
        data = await uploadPromise(params);
    } catch (error) {
        throw error;
    }

    return data;
};

then retrun :

getPptLink = async (request, response) => {
        const { user, body: { rootId } } = request;
        
        const link = await ppt.getCoursePpt(rootId, user);
        response.json({ link });

        heapdump.writeSnapshot('/' + Date.now() + '.heapsnapshot');
        heapdump.writeSnapshot(function (err, filename) {
            console.log('dump4 written to', filename);
        });
    };
0

There are 0 answers