UNPKG

@nearform/heap-profiler

Version:

Heap dump, sample profiler and allocation timeline generator for Node.

98 lines (79 loc) 2.43 kB
'use strict' const { Session } = require('inspector') const { writeFile } = require('fs') const { ensurePromiseCallback, destinationFile, validateDestinationFile } = require('./utils') const defaultInterval = 32768 const defaultDuration = 10000 module.exports = function generateHeapSamplingProfile(options, cb) { /* istanbul ignore if */ if (typeof options === 'function') { cb = options options = null } // Prepare the context const { interval, duration, destination, signal } = Object.assign( { interval: defaultInterval, duration: defaultDuration, destination: destinationFile('heapprofile') }, options ) const [callback, promise] = ensurePromiseCallback(cb) const session = new Session() let timeout if (typeof destination !== 'string' || destination.length === 0) { callback(new Error('The destination option must be a non empty string')) return } if (typeof duration !== 'number' || isNaN(duration) || duration < 0) { callback(new Error('The duration option must be a number greater than 0')) return } if (typeof interval !== 'number' || isNaN(interval) || interval < 0) { callback(new Error('The interval option must be a number greater than 0')) return } if (signal) { if (signal.aborted) { callback(new Error('The AbortController has already been aborted')) return } if (signal.addEventListener) { signal.addEventListener('abort', finish) } else { signal.once('abort', finish) } } function finish() { clearTimeout(timeout) session.post('HeapProfiler.stopSampling', (err, profile) => { /* istanbul ignore if */ if (err) { return callback(err) } session.disconnect() writeFile(destination, JSON.stringify(profile.profile), 'utf-8', err => { /* istanbul ignore if */ if (err) { return callback(err) } callback(null, destination) }) }) } validateDestinationFile(destination, err => { if (err) { return callback(err) } // Start the session session.connect() // Request profile session.post('HeapProfiler.startSampling', { samplingInterval: interval }, err => { /* istanbul ignore if */ if (err) { return callback(err) } if (!signal) { timeout = setTimeout(finish, duration) } }) }) return promise }