Skip to content

warning: possible EventEmitter memory leak detected  #64

Open

Description

@benoitguigal

I am using factor-bundle with watchify and gulp.

var gulp = require('gulp');
var gutil = require('gulp-util');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var reactify = require('reactify');
var watchify = require('watchify');
var factor = require('factor-bundle');
var uglify = require('gulp-uglify');
var fs = require('fs');
var concat = require('concat-stream');
var file = require('gulp-file');

gulp.task('watch', bundle)

function bundle () {

  // react components
  var files = [
    '/path/to/file1.jsx',
    '/path/to/file2.jsx',
    '/path/to/file3.jsx'
  ];


  var bundler = watchify(browserify(watchify.args)) 

  bundler.add(files);
  bundler.add('./lib/api.js', {expose: 'api'});
  bundler.require('./lib/api.js', {expose: 'api'});
  bundler.transform('reactify');
  bundler.on('update', rebundle);

  function rebundle() {
    bundler.plugin('factor-bundle', {
        outputs: [
          write('/path/to/file1.js'),
          write('/path/to/file2.js'),
          write('/path/to/file3.js'),
          ]
    });
    bundler.bundle()
        .on('error', gutil.log.bind(gutil, 'Browserify Error'))
        .pipe(write('shared.js'));
  };

  return rebundle();
}


function write (name) {
    return concat(function (content) {
        // create new vinyl file from content and use the basename of the
        // filepath in scope as its basename.
        return file(name, content, { src: true })
        // uglify content
        .pipe(uglify())
        // write content to build directory
        .pipe(gulp.dest('./public/bundles/'))
    });
}

It works fine but after five or ten rebundles I start seeing the following warning:

Trace
    at Browserify.addListener (events.js:179:15)
    at f (/Users/benoit/git/figure/web/node_modules/factor-bundle/index.js:55:7)
    at Browserify.plugin (/Users/benoit/git/figure/web/node_modules/browserify/index.js:345:9)
    at Browserify.bundle (/Users/benoit/git/figure/web/gulpfile.js:46:13)
    at Browserify.emit (events.js:107:17)
    at null._onTimeout (/Users/benoit/git/figure/web/node_modules/watchify/index.js:126:15)
    at Timer.listOnTimeout (timers.js:110:15)
(node) warning: possible EventEmitter memory leak detected. 11 finish listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
    at ConcatStream.addListener (events.js:179:15)
    at ConcatStream.once (events.js:204:8)
    at Labeled.Readable.pipe (/Users/benoit/git/figure/web/node_modules/factor-bundle/node_modules/labeled-stream-splicer/node_modules/stream-splicer/node_modules/readable-stream/lib/_stream_readable.js:612:8)
    at /Users/benoit/git/figure/web/node_modules/factor-bundle/index.js:73:43
    at Array.reduce (native)
    at Transform._flush (/Users/benoit/git/figure/web/node_modules/factor-bundle/index.js:65:35)
    at Transform.<anonymous> (/Users/benoit/git/figure/web/node_modules/factor-bundle/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:135:12)
    at Transform.g (events.js:199:16)
    at Transform.emit (events.js:129:20)
    at finishMaybe (/Users/benoit/git/figure/web/node_modules/factor-bundle/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:371:12)
    at endWritable (/Users/benoit/git/figure/web/node_modules/factor-bundle/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:378:3)
    at Transform.Writable.end (/Users/benoit/git/figure/web/node_modules/factor-bundle/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:356:5)
(node) warning: possible EventEmitter memory leak detected. 11 finish listeners added. Use emitter.setMaxListeners() to increase limit.

Activity

  1. neilcarpenter commented on Apr 8, 2015

    @neilcarpenter

    +1

  2. Freyert commented on Apr 8, 2015

    @Freyert

    Yeah, this is for real. Every time the plugin is called the addHooks event listener is attached to Browserify. As you can see in this illustration

     [ [Function: collect],
      [Function: reset],
      [Function],
      [Function: addHooks],
      [Function: addHooks],
      [Function: addHooks],
      [Function: addHooks],
      [Function: addHooks],
      [Function: addHooks],
      [Function: addHooks],
      [Function: addHooks],
      [Function: addHooks],
      [Function: addHooks],
      [Function: addHooks] ]
    

    Just add: bundler.on('reset', function () { gutil.log(bundler.listeners('reset')); });, to see the results yourself. I'm guessing this probably leads to the excessive listeners on ConcatStream.

  3. Freyert commented on Apr 8, 2015

    @Freyert

    @benoitguigal to fix this do this to your rebundle function:

      var outputs;
      bundler.plugin('factor-bundle', {
        outputs: outputs
      }); 
      function rebundle() {
        outputs = files.map(function (file) {
          var name = path.basename(file, '.jsx');
          return write("./" + name + '.js');
        }); 
    
        bundler.bundle()
        .on('error', gutil.log.bind(gutil, 'Browserify Error'))
        .pipe(write('shared.js'));
      }
    

    And please give me that bounty on SO 😃

  4. terinjokes commented on Apr 8, 2015

    @terinjokes
    Contributor

    This seems like a real bug, looking into it. addHooks should only be added once, you can see it's the saem logic as in watchify: https://github.com/substack/watchify/blob/e20c9a39fad48f411b2dc48a1d784a947bb8fb9e/index.js#L59-L60

  5. Freyert commented on Apr 9, 2015

    @Freyert

    So my SO solution doesn't work right. Luckily I have another solution in the interim until a PR is made.

    So try this: Edit node_modules/factor-bundle/index.js and change

    From
    b.on('reset', addHooks);
    to
    b.once('reset', addHooks);

    Your original code should work.

  6. benoitguigal commented on Apr 9, 2015

    @benoitguigal
    Author

    Thanks Freyert, I will give it a try :-)

  7. neilcarpenter commented on Apr 9, 2015

    @neilcarpenter

    Cheeeers, has fixed for me

  8. Freyert commented on Apr 9, 2015

    @Freyert

    BTW @benoitguigal and @neilcarpenter nice sites/projects.

  9. neilcarpenter commented on Apr 9, 2015

    @neilcarpenter

    Haha thanks!! :) And yeah, ditto to @benoitguigal

  10. johnnyshankman commented on Jun 15, 2015

    @johnnyshankman

    +1, is there still no PR or merged code for this?

  11. kennethaasan commented on Jul 30, 2015

    @kennethaasan

    +1

  12. davidchase commented on Oct 14, 2015

    @davidchase

    this seems to be an issue still with 2.5.0 on Mac OSX

    browserify ./client/src/app/*.js -p  [ factor-bundle  -o 'uglifyjs -cm > ./client/dist/js/`basename $FILE`' ] -o ./client/dist/js/common.js

    the above "fix" does not solve the issue...

  13. johnnyshankman commented on Dec 2, 2015

    @johnnyshankman

    This was still a problem I had in my grunt karma task

    Running "karma:ci" (karma) task
    (node) warning: possible EventEmitter memory leak detected. 11 bundled listeners added. Use emitter.setMaxListeners() to increase limit.
    Trace
        at Browserify.addListener (events.js:179:15)
        at Browserify.once (events.js:204:8)
        at deferredBundle (/Users/user/Documents/feed/node_modules/karma-bro/lib/bro.js:183:11)
        at Browserify.w.bundleFile (/Users/user/Documents/feed/node_modules/karma-bro/lib/bro.js:243:7)
        at /Users/user/Documents/feed/node_modules/karma-bro/lib/bro.js:269:9
        at nextPreprocessor (/Users/user/Documents/feed/node_modules/karma/lib/preprocessor.js:48:28)
        at /Users/user/Documents/feed/node_modules/karma/lib/preprocessor.js:86:7
        at evalmachine.<anonymous>:334:14
        at /Users/user/Documents/feed/node_modules/karma/node_modules/graceful-fs/graceful-fs.js:102:5
        at FSReqWrap.oncomplete (evalmachine.<anonymous>:95:15)
    Injecting Rewireify into modules
    

    I got it to stop by trying this line for an arbitrary number n:

    require('events').EventEmitter.prototype._maxListeners = n;
    

    I continued to get warnings that I had n+1 bundled listeners until I finally set _maxlistners to 103 or larger.

    So if you're willing to sit down and find out how many listeners you've been adding, you can at least silence the warning by using the line above somewhere in the global scope.

  14. Emnalyeriar commented on Jan 7, 2016

    @Emnalyeriar

    I defined my browserify + watchify task exacly as here and got this problem as well.

    (node) warning: possible EventEmitter memory leak detected. 11 reset listeners added. Use emitter.setMaxListeners() to increase limit.
    
  15. Liero commented on Jul 20, 2016

    @Liero

    Why this has not been fixed yet?

  16. Liero commented on Jul 20, 2016

    @Liero

    I used this ugly workaround, since I was not able to extract the plugin outside rebundle function

    ** 
     * fixes possible EventEmitter memory leak detected: https://github.com/substack/factor-bundle/issues/64
     * @param {Browserify.BrowserifyObject} bundler
     */
    function fixFactorBundleMemoryLeak(bundler) {
      var listeners = bundler.listeners("reset").filter(l => l.name === "addHooks");
      for (var i = 0; i < listeners.length - 1; i++) { //remove "reset" listeners except last
        bundler.removeListener('reset', listeners[i]);
      }
    }
    
  17. added a commit that references this issue on Jul 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions