v13.4.1: bugs, docker, and localization

11 views
Skip to first unread message

Evan Tahler

unread,
May 23, 2016, 8:14:16 PM5/23/16
to actionHero.js
https://github.com/evantahler/actionhero/releases/tag/v13.4.1

Web Server File Sending Memory Leak fix

When sending files via HTTP in ActionHero, we make use of pipes to efficiently stream files to clients, ie: fs.createReadStream(file).pipe(response). We noticed that if your ActionHero sends a lot of files, it was possible to end up with a memory leak, as a growing number of connections would remain in RAM as they were still denoted as "sending data", even when they might not be.

We use the request.finish() even to clean up the connection, and this worked well 99% of the time. However, if there was an issue with the transfer (premature client hangup, networking error, etc), thatfinish event would never be called. We now also listen for a close event, which catches these error cases.

api.chatRoom.list

Tasks: Bring your own workers

Extending/modifying the functionality of Resque within ActionHero has been cumbersome and has made upgrading deployments troublesome. We now have a new section in config/tasks.js to allow developers to replace the existing queues, scheduler, and multiWorkers with custom implementations.

For Example:

'use strict';

var NR = require('node-resque');
var pluginRunner = require('../node_modules/node-resque/lib/pluginRunner.js');

//noinspection JSUnresolvedVariable
module.exports = {
  loadPriority:  590,
  initialize: function(api, next){
    api.customResque = {};

    let customQueue = NR.queue;

    customQueue.prototype.enqueueFront = function(q, func, args, callback){
      var self = this;
      if(arguments.length === 3 && typeof args === 'function'){
        callback = args;
        args = [];
      }else if(arguments.length < 3){
        args = [];
      }

      args = arrayify(args);
      var job = self.jobs[func];
      pluginRunner.runPlugins(self, 'before_enqueue', func, q, job, args, function(err, toRun){
        if(toRun === false){
          if(typeof callback === 'function'){ callback(err, toRun); }
        }else{
          self.connection.redis.sadd(self.connection.key('queues'), q, function(){
            self.connection.redis.lpush(self.connection.key('queue', q), self.encode(q, func, args), function(){
              pluginRunner.runPlugins(self, 'after_enqueue', func, q, job, args, function(){
                if(typeof callback === 'function'){ callback(err, toRun); }
              });
            });
          });
        }
      });
    };

    api.customResque.queue = customQueue;

    next();
  }
};

Localization Updates

  • Added a general localization helper via api.i18n.localize(string, options) orapi.i18n.localize([string-with-interpolation, value], options).
  • Localized the chat room errors
  • Localized the cache errors
  • by @l0oky via #837

Docker Example

  • Created a docker image (evantahler/actionhero) which will auto-build from master and contain a sample actionhero project from the latest public NPM version
FROM alpine:3.3
MAINTAINER ad...@actionherojs.com

RUN apk add --update nodejs
RUN npm install actionhero
RUN ./node_modules/.bin/actionhero generate
RUN npm install

CMD ["node", "./node_modules/.bin/actionhero", "start"]
EXPOSE 8080 5000

Fixed direct access of servers via api.servers.servers

  • api.servers.servers is now properly constructed via {} rather than []
  • by @TobiTonner via #846

Misc

  • use a much simpler publication method to build and publish www.actionhero.com; remove submodule dependency from the project.
  • eslint updated to v2.10.0
  • should updated to v8.3.2
  • mocha updated to v2.5.1
  • node-resque updated to v2.0.5
  • misc test updates which will hopefully make Travis.ci happier, and report less intermittent failures.
Reply all
Reply to author
Forward
0 new messages