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
api.chatRoom.list(callback)
-> callback returns error
and rooms
, which is an array of String names of your roomsExtending/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(); } };
api.i18n.localize(string, options)
orapi.i18n.localize([string-with-interpolation, value], options)
.evantahler/actionhero
) which will auto-build from master and contain a sample actionhero project from the latest public NPM versionFROM 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
api.servers.servers
is now properly constructed via {}
rather than []
www.actionhero.com
; remove submodule dependency from the project.eslint
updated to v2.10.0should
updated to v8.3.2mocha
updated to v2.5.1node-resque
updated to v2.0.5