@nearform/heap-profiler
Advanced tools
Comparing version 0.6.2 to 0.7.0
{ | ||
"name": "@nearform/heap-profiler", | ||
"version": "0.6.2", | ||
"version": "0.7.0", | ||
"description": "Heap dump, sample profiler and allocation timeline generator for Node.", | ||
@@ -15,2 +15,6 @@ "author": "NearForm Ltd", | ||
"url": "https://github.com/feugy" | ||
}, | ||
{ | ||
"name": "Matteo Collina", | ||
"url": "https://github.com/mcollina" | ||
} | ||
@@ -46,6 +50,7 @@ ], | ||
"test": "tap --gc --reporter=spec --coverage-report=html --coverage-report=text --no-browser test/*.spec.js", | ||
"ci": "npm run lint && tap --gc --no-color --reporter=spec --coverage-report=json --coverage-report=text --branches 90 --functions 90 --lines 90 --statements 90 --timeout 45 test/*.spec.js" | ||
"ci": "npm run lint && tap --gc --no-color --reporter=spec --coverage-report=json --coverage-report=text --branches 90 --functions 90 --lines 90 --statements 90 --timeout 180 test/*.spec.js" | ||
}, | ||
"dependencies": { | ||
"sonic-boom": "^1.0.1" | ||
"sonic-boom": "^1.0.1", | ||
"abort-controller": "^3.0.0" | ||
}, | ||
@@ -52,0 +57,0 @@ "devDependencies": { |
@@ -79,2 +79,3 @@ # @nearform/heap-profiler | ||
- `duration`: Sample duration, in milliseconds. Default is `10000` (10 seconds). | ||
- `signal`: the [AbortController](http://npm.im/abort-controller) `signal`. | ||
@@ -81,0 +82,0 @@ - `recordAllocationTimeline([options], [callback]): [function|Promise]`: Starts recording allocation on heap. The valid options are: |
@@ -6,2 +6,3 @@ 'use strict' | ||
const recordAllocationTimeline = require('./timeline') | ||
const AbortController = require('abort-controller') | ||
@@ -52,3 +53,3 @@ function benchmarkGeneration(logger, type, report, options, cb) { | ||
if ('HEAP_PROFILER_PROFILE_DURATION' in process.env) { | ||
profilerOptions.duration = parseInt(process.env.HEAP_PROFILER_PROFILE_DURATION, 10) | ||
profilerOptions.duration = parseInt(process.env.HEAP_PROFILER_PROFILE_DURATION, 10) || 10000 // 10s | ||
} | ||
@@ -93,3 +94,11 @@ | ||
if (takeProfile) { | ||
benchmarkGeneration(logger, 'sampling profile', generateHeapSamplingProfile, profilerOptions, onToolEnd) | ||
const controller = new AbortController() | ||
profilerOptions.signal = controller.signal | ||
const abort = controller.abort.bind(controller) | ||
process.once('SIGUSR2', abort) | ||
// logger.info(`[@nearform/heap-profiler] Sampling profiler started. Awaiting ${profilerOptions.duration} ms or SIGUSR2 to stop ...`) | ||
benchmarkGeneration(logger, 'sampling profile', generateHeapSamplingProfile, profilerOptions, function (err) { | ||
process.removeListener('SIGUSR2', abort) | ||
onToolEnd(err) | ||
}) | ||
} | ||
@@ -96,0 +105,0 @@ |
@@ -18,3 +18,3 @@ 'use strict' | ||
// Prepare the context | ||
const { interval, duration, destination } = Object.assign( | ||
const { interval, duration, destination, signal } = Object.assign( | ||
{ interval: defaultInterval, duration: defaultDuration, destination: destinationFile('heapprofile') }, | ||
@@ -25,2 +25,3 @@ options | ||
const session = new Session() | ||
let timeout | ||
@@ -39,2 +40,35 @@ if (typeof destination !== 'string' || destination.length === 0) { | ||
if (signal) { | ||
if (signal.aborted) { | ||
callback(new Error('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 => { | ||
@@ -55,21 +89,3 @@ if (err) { | ||
setTimeout(() => { | ||
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) | ||
}) | ||
}) | ||
}, duration) | ||
timeout = setTimeout(finish, duration) | ||
}) | ||
@@ -76,0 +92,0 @@ }) |
@@ -6,2 +6,4 @@ 'use strict' | ||
const { file: tmpFile } = require('tmp-promise') | ||
const AbortController = require('abort-controller') | ||
const EventEmitter = require('events') | ||
@@ -24,2 +26,51 @@ const generateHeapSamplingProfile = require('../src/profile') | ||
t.test('abort controller', async t => { | ||
const { path: destination, cleanup } = await tmpFile() | ||
const controller = new AbortController() | ||
const start = Date.now() | ||
setTimeout(function() { | ||
controller.abort() | ||
}, 100) | ||
await Promise.race([generateHeapSamplingProfile({ destination, signal: controller.signal }), allocateMemoryFor(1000)]) | ||
const end = Date.now() | ||
const generated = JSON.parse(readFileSync(destination, 'utf-8')) | ||
t.is(end - start < 1000, true) | ||
t.is(end - start >= 100, true) | ||
t.true(validate(generated)) | ||
cleanup() | ||
}) | ||
t.test('abort with EventEmitter', async t => { | ||
const { path: destination, cleanup } = await tmpFile() | ||
const controller = new EventEmitter() | ||
const start = Date.now() | ||
setTimeout(function() { | ||
controller.emit('abort') | ||
}, 100) | ||
await Promise.race([generateHeapSamplingProfile({ destination, signal: controller }), allocateMemoryFor(1000)]) | ||
const end = Date.now() | ||
const generated = JSON.parse(readFileSync(destination, 'utf-8')) | ||
t.is(end - start < 1000, true) | ||
t.is(end - start >= 100, true) | ||
t.true(validate(generated)) | ||
cleanup() | ||
}) | ||
t.test('it correctly generates a profile using callbacks', async t => { | ||
@@ -26,0 +77,0 @@ const { path: destination, cleanup } = await tmpFile() |
@@ -12,3 +12,3 @@ 'use strict' | ||
const duration = 10 | ||
const timeout = 5000 | ||
const timeout = 10000 | ||
@@ -15,0 +15,0 @@ t.test('it correctly generates a timeline using promises', { timeout }, async t => { |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
48922
1019
121
2
1
+ Addedabort-controller@^3.0.0
+ Addedabort-controller@3.0.0(transitive)
+ Addedevent-target-shim@5.0.1(transitive)