actionhero

Actionhero is a realtime multi-transport nodejs API Server with integrated cluster capabilities and delayed tasks

APACHE-2.0 License

Downloads
14.5K
Stars
2.4K
Committers
127

Bot releases are visible (Hide)

actionhero - v13.2.3: updates

Published by evantahler over 8 years ago

Updates

Bugs

  • Fixed a bug wherein the server's logging locale could not be changed from en
actionhero - v13.2.2: Fixing tedious things

Published by evantahler over 8 years ago

Code Style Guide

We now have an actionhero code style guide! When working on Actionhero, be sure that your IDE/Editor has support for eslint. We also now have contribution guides for the project: https://github.com/evantahler/actionhero/blob/master/CONTRIBUTING.md. I don't get the Lavendarman reference, but the file is full of good advice anyway!

Public files with spaces in the name

Fixed a bug which prevented static files with spaces in their names from being sent to clients

Windows

Oh windows... why did you have to do everything differently than every other operating system? Even your path delimiters (\ vs /) go the wrong way. Anyway... the Actionhero test suite now runs on windows!

Fix worker IDs in Actionhero cluster

Fixed a bug which would report and log actionhero worker names with repeat IDs when running startCluster with a worker count above 10.

Misc

  • Documentation Updates:
    • Style and Linting (@synthmeat)
    • NODE_ENV vs developmentMode
    • ... and more!
actionhero - v13.2.1: Squashing Bugs

Published by evantahler over 8 years ago

Bugs

actionhero - v13.2.0: Node Resque Fix

Published by evantahler over 8 years ago

From node resque: https://github.com/taskrabbit/node-resque/pull/121

This is a (potentially) breaking change

When comparing this project to ruby resque, we had been using the wrong value (key pointer) in the delayed job queue. When running this project alongside a ruby scheduler, it was possible for older timestamp key set entries not to be deleted. This update corrects the difference.

When upgrading to this new version, it is very likely you will end up with queue artifacts that are not properly deleted, which have the potential to break plugin's behaviors. This will require manual intervention to remove keys that match resque:timestamps:*. Before upgrading to this version, the safest path forward is to drain all of your queues and schedules first, using the previous version of node-resque.


As far as actionhero is concerned, this issue would only effect you if your application uses scheduler and api.tasks.enqueueAt or api.tasks.enqueueIn directly. This is why we have made this a minor version update.

actionhero - v13.1.1: BugFix for developer mode

Published by evantahler over 8 years ago

Bugfixes:

actionhero - v13.1.0: api.cache.list

Published by evantahler over 8 years ago

List methods

by @evantahler via https://github.com/evantahler/actionhero/pull/779

api.cache implements a distributed shared list. 3 simple functions are provided to interact with this list, push, pop, and listLength. These lists are stored in Redis, and cannot be locked. That said, a push and pop operation will guarantee that one-and-only-one copy of your data is returned to whichever application acted first (when popping) or an error will be returned (when pushing).

api.cache.push

  • Invoke: api.cache.push(key, data, next)
    • data must be serializable via JSON.stringify
  • Callback: next(error)

api.cache.pop

  • Invoke: api.cache.pop(key, next)
  • Callback: next(error, data)
    • data will be returned in the object form it was saved (array, object, string)

api.cache.listLength

  • Invoke: api.cache.listLength(key, next)
  • Callback: next(error, length)
    • length will be an integer.
    • if the list does not exist, 0 will be returned

Misc

  • Remove entries from startingChatRooms so new projects don't have to override this setting [https://github.com/evantahler/actionhero/commit/692fde7cb388bf3d0edb05d9defd8ec8fae9b55d]
  • Fix a shutdown bug for crashes when the task multiWorker has not yet started up [https://github.com/evantahler/actionhero/commit/142a09ed6cd1550616532a52bb4e6a8549be5736]
actionhero - v13.0.5: Hotfix for the Hotfix

Published by evantahler over 8 years ago

The previous release had an error in the syntax of a warning message which would crash on on some operating systems.

https://github.com/evantahler/actionhero/commit/bca3b002e5922bb84a8b56a4751d267d66092ee2

actionhero - v13.0.4: Redis subscription updates Hotfix

Published by evantahler over 8 years ago

[Hotfix] Redis Subscription Updates

With some redis libraries (identified in ioredis), when using sentinels to connect to redis, it was possible to have an Unhandled rejection error. This update changes the order in which subscriptions happen in relation to the connection callback.

actionhero - v13.0.3 Cluster Flapping Detection

Published by evantahler over 8 years ago

Flapping

When running actionhero startCluster, we we will now detect is the workers/servers under the cluster are rapidly crashing with either an uncaughtException or unhandledRejection. By default, we will check every 30 seconds for this, and if the number of these errors is greater than 2x expected number of workers (set with the --workers flag), the cluster will exit.

actionhero - v13.0.2: Plugin Static File Hotfix

Published by evantahler over 8 years ago

[HOTFIX] - When linking plugins with public directories, their /public directories should be sourced by the static file server.
We should not modify api.config.general.paths.public to do this.

actionhero - v13.0.1: StartCluster Hotfix

Published by evantahler over 8 years ago

Bugs

Fixes a bug in which actionhero startCluster would fail if the log directory was a symlink

actionhero - v13.0.0

Published by evantahler over 8 years ago

v13.0.0

A number of changes (below) have updated the capabilities of the actionhero binary. The new list (and help.txt) is:

actionhero - A multi-transport node.js API Server with integrated cluster capabilities and delayed tasks

Binary options:
* help (default)
* start
* startCluster
* generate
* generateAction
* generateTask
* generateInitializer
* generateServer
* actions
* enqueueTask
* console
* link

Descriptions:

* actionhero help
  will display this document

* actionhero start --config=[/path/to/config.js] --title=[processTitle]  --daemon
  will start a template actionhero server
  this is the respondent to "npm start"
  [config] (optional) path to config.js, defaults to "process.cwd() + '/' + config.js". You can also use ENV[ACTIONHERO_CONFIG].
  [title] (optional) process title to use for actionhero-s ID, ps, log, and pidFile defaults. Must be unique for each member of the cluster.  You can also use ENV[ACTIONHERO_TITLE]. Process renaming does not work on OSX/Windows
  [daemon] (optional) to fork and run as a new background process defaults to false

* actionhero startCluster --workers=[numWorkers]  --daemon
  will launch a actionhero cluster (using node-s cluster module)
  [workers] (optional) number of workers (defaults to # CPUs - 2)
  [daemon] (optional) to fork and run as a new background process defaults to false

* actionhero generate
  will prepare an empty directory with a template actionhero project

* actionhero generateAction --name=[name] --description=[description] --inputsRequired=[inputsRequired] --inputsOptional=[inputsOptional]
  will generate a new action in "actions"
  [name] (required)
  [description] (required) should be wrapped in quotes if it contains spaces

* actionhero generateTask --name=[name] --description=[description] --scope=[scope] --frequency=[frequency]
  will generate a new task in "tasks"
  [name] (required)
  [description] (required) should be wrapped in quotes if it contains spaces
  [scope] (optional) can be "any" or "all"
  [frequency] (optional)

* actionhero generateInitializer --name=[name]
  will generate a new initializer in "initializers"
  [name] (required)

* actionhero generateServer --name=[name]
  will generate a new server in "servers"
  [name] (required)

* actionhero actions
  will list all actions in this server to stdout

* actionhero enqueueTask --name=[taskName] --args=[JSON-formatted args]
  will enqueue a task into redis

* actionhero console
  will open an interactive CLI with the API object in scope.
  this is sometimes called a REPL

* actionhero link --name=[pluginName]
  will link the actions, tasks, initializers, etc from a plugin into your top-level project
  normally, you will have first installed the plugin via `npm install myPlugin`

#############################################################
## More Help & the actionhero documentation can be found @ ##
##             http://www.actionherojs.com                 ##
#############################################################

Localization Tooling

(by @evantahler via https://github.com/evantahler/actionhero/pull/756)

This allows localization of responses to connections and the api server logs using the i18n node module.

Locale files

  • When running actionhero with api.config.i18n.updateFiles = true, you will see actionhero generate a 'locales' folder at the top level of your project which will contain translations of all strings in your project with are passed though the new localization system. This includes all uses of connection.localize and api.log.
    • be sure to use sprintf-style string interpolation for variables!
  • From here, it is an easy matter to change the strings, per locale, to how you would like them presented back in your application
  • disable api.config.i18n.updateFiles if you do not want this behavior.

Determining connection locales

Since every actionhero implementation is unique, we cannot ship with a "guess" about how to determine a given connection's locale. Perhaps you have an HTTP server and you can trust your client's accept-language headers. Or perhaps you run your API under a number of different host names and you can presume locale based on them. Whatever the case, you need to create a synchronous method in an initializer which will be called when each connection connects to return its locale.

For example, I may have an initializer in my project like this:

module.exports = {
  initialize: function(api, next){
    api.customLocalization = {
      lookup: function(connection){
        var locale = 'en';
        if(connection.type === 'web'){
          if(connection.rawConnection.req.headers.host === 'usa.site.com'){ locale = 'en-US'; }
          if(connection.rawConnection.req.headers.host === 'uk.site.com'){  locale = 'en-GB'; }
          if(connection.rawConnection.req.headers.host === 'es.site.com'){  locale = 'es-ES'; }
          if(connection.rawConnection.req.headers.host === 'mx.site.com'){  locale = 'es-MX'; }
        }

        return locale;
      }
    }


    next();
  }
}

To tell the i18n to use this method with a new connection, set api.config.i18n.determineConnectionLocale = 'api.customLocalization.lookup'

New Config Settings

  • config/errors.js has been completely redone to take advantage of connection.localize
  • config/i18n:
exports.default = {
  i18n: function(api){
    return {
      // visit https://github.com/mashpie/i18n-node to see all configuration options
      // locale path can be configired from within ./config/api.js
      locales: ['en'],
      fallbacks: {
        'en-US': 'en',
      },

      updateFiles: true,

      // this will configure logging and error messages in the log(s)
      defaultLocale: 'en',

      // the name of the method by which to determine the connection's locale
      // by default, every request will be in the 'en' locale
      // this method will be called witin the localiazation middleware on all requests
      determineConnectionLocale: 'api.i18n.determineConnectionLocale',
    }
  }
};

exports.procution ={
  i18n: function(api){
    return {
      updateFiles: false
    }
  }
}

Connection Methods:

  • connection.localize(string) or connection.localize([string-with-interpolation, value])
    • Allows you to interpolate a string based on the connection's current locale. For example, say in an action you wanted to respond with data.response.message = connection.localize('the count was %s', 4); In your locale files, you would define the count was %s in every language you cared about, and not need to modify the action itself at all.

Logger Updates:

  • Just like connections, the actionhero logger itself now has localization interpolation built in. Note how in the new settings you set which locale you want the server's logs to be expressed in. Using that, you can now use sprintf-style string interpolation as the first argument of api.log()
    • You might want to log the message api.log(['The time is %s', new Date()], 'alert').
    • Changing the translation of the string The time is %s in your locale files would apply to the logger as well!
    • You can of course continue to log plain strings as we have been with the logger as well.

Linked Plugins

  • create the binary command actionhero link --name=name_of_plugin
  • remove the plugin-specific code from the config initializer
  • remove the old plugin tests

Plugin Registration

When running actionhero link --name=name_of_plugin, we look though your api.config.general.paths.plugin (which contains ./node_modules by default) for the named plugin. If we find it, we link in the actions, initializers, tasks, and servers found there. These files will then be "present" in your project via that linkfile. A linkfile is a simple file with the name of {pluginName}.link in the top level folder of that type of thing (like actions or tasks)

For example, if you install myPlugin via npm install --save myPlugin into your project's ./node_modules folder, and then npm run actionhero link --name myPlugin, this will work perfectly.

Files found in the /config directory of the plugin will be copied into your project's top level config directory. This is under the assumption that you will want to modify these settings. Config files within a plugin itself will not get sourced.

A previous version of this tool used OS symlinks, but that was removed to enable cross-platform compatibility.

Nested Plugins (TODO)

The good news is that we can count on NPM to properly (relatively) install any dependent plugins as a child in their local node_modules, so it shouldn't be too hard.

Notes for Plugin Authors

  • There should be no more postinstall scripts needed
  • Remember that any files in /config will get automatically copied into the user's project when they run actionhero link. Make sure that you have some good comments!
  • Be sure that your plugin is OS-independant. Use path.sep for file path separators and things like that. Use relative paths for everything in your plugin.

Remove Domains + actionDomains from the project.

Remove Grunt; more Actionhero-binary commands

Input methods have api set as this.

Misc

actionhero - v12.5.0 resque config change

Published by evantahler almost 9 years ago

This change renames the variable package in redis config to pkg. package is a reserved word in javascript and should not have been used.

The package node-resque, which actionhero relies on, has also updated this configuration setting.

actionhero - v12.4.1: matchTrailingPathParts (+last release for node < v4.0.0)

Published by evantahler almost 9 years ago

FORWARD WARNING: This is likely to be the last update to actionhero which supports node versions less than 4.0.0.

Many of the packages we depend on are moving to target the LTS release of 4.2.2 as their minimum build. Actionhero will be following suit. Version 13.0.0 will have a target of node >=4.0.0


Release Notes

matchTrailingPathParts in router

Enables a new option, matchTrailingPathParts which you can enable in the router to match combination paths:

post: [
  // yes match: site.com/api/123
  // no match: site.com/api/123/admin
  { path: '/login/:userId(/.*/)', action: 'login' }
],

post: [
  // yes match: site.com/api/123
  // yes match: site.com/api/123/admin
  { path: '/login/:userId(/.*/)', action: 'login', matchTrailingPathParts: true }
],

This also enables "catch all" routes, like:

get: [
  { path: ':path(/.*/)', action: 'catchAll', matchTrailingPathParts: true }
],

If you have a route with multiple variables defined and matchTrailingPathParts is true, only the final segment will match the trailing sections:

get: [
  // the route site.com/users/123/should/do/a/thing would become {userId: 123, path: '/should/do/a/thing'}
  { path: '/users/:userId/:path(/.*/)', action: 'catchAll', matchTrailingPathParts: true }
],

by @evantahler via https://github.com/evantahler/actionhero/pull/728

Misc Updates

actionhero - v12.4.0: Utils and Logging

Published by evantahler almost 9 years ago

Remove old utils

There were a number of old methods within the api.utils namespace which we are not using. Some of them were actually quite dangerous. They are gone now.

  • Removed methods:
    • api.utils.sqlDateTime(time)
    • api.utils.sqlDate(time)
    • api.utils.randomString(chars)
    • api.utils.sleepSync(seconds)
    • api.utils.randomArraySort(arr)
    • api.utils.inArray(haystack, needle)
  • by @evantahler via https://github.com/evantahler/actionhero/pull/714

Task logging verbosity configuration options

  • allow for custom logging options for worker/task/scheduler options
  • defaults are now:
workerLogging : {
  failure   : 'error', // task failure
  success   : 'info',  // task success 
  start     : 'info',
  end       : 'info',
  cleaning_worker : 'info',
  poll      : 'debug',
  job       : 'debug',
  pause     : 'debug',
  internalError : 'error',
  multiWorkerAction : 'debug'
},

// Logging levels of the task scheduler
schedulerLogging : {
  start     : 'info',
  end       : 'info',
  poll      : 'debug',
  enqueue   : 'debug',
  reEnqueue : 'debug',
  working_timestamp : 'debug',
  transferred_job   : 'debug'
},

Fixed issue with websockets remaining open

Documentation Updates

  • More information/examples about how to run actionhero in either serveror worker mode
actionhero - v12.3.0: QS and Logging Updates

Published by evantahler almost 9 years ago

Use QS to enable array and complex param parsing for the web server

  • The [qs](https://github.com/hapijs/qs) package (originally from TJ Holowaychuk, and now maintained by the Hapi.JS team) is an excellent query-string parsing library made to expand upon and replace node's built-in url.parse. It handles more esoteric cases like merging ?collection[]=first&collection[]=second into an array containing both 'first' and 'second'. More importantly, It allows you to configure how to handle special cases of posting object, deeply nested params, etc.
  • Actionhero maintains its stance of shipping with support for these advanced/fancy/not-in-spec params disabled, but now you can customize this behavior as you see fit via the new api.config.servers.queryParseOptions, which will be passed to the qs parser.
  • via @evantahler by https://github.com/evantahler/actionhero/pull/711

Winston 2.0

  • Upgrade actionhero to use winston v2.x.x as our logger.
  • This new version of Winston fixes a number of long-standing bugs with how they handled log levels. Winston now confirms to the standard RFC 5424, which matches both node itself and npm. This allows us to remove our custom loggers in favor of the defaults.
  • Reverting to a uniform logging specification required that we remove actionhero's custom trace log level, which is a reversion of https://github.com/evantahler/actionhero/pull/595, which we added in February of this year. This means that if you run your actionhero server with the log level of debug, you will now see messages which had been previously tagged as trace.
    • I expect more conversation on this topic to unfold. This release has been cut before that so that we can be starting from a common RFC baseline, and move up from there.
  • You can now customize the logger's behavior You can customize these via api.config.logger.levels and api.config.logger.colors. See Winston's documenation for more information. This will allow you do bring back trace and other custom log levels for your actions/initializers.

Documentation Fixes and Updates

actionhero - v12.2.3: Web Memory Leak Fix + Packages

Published by evantahler almost 9 years ago

Update requirements to compatible-with

  • This changes the package requirements to compatible-with deps instead of hard-coded version numbers. Hopefully this will help prevent immediate failures if packages get unpublished in the future, like node-uuid 1.4.3 did.
  • by @crrobinson14 via https://github.com/evantahler/actionhero/pull/703

fix web+connection memory leak

Oh, and we have a new documentation website! Check out http://www.actionherojs.com/docs

actionhero - v12.2.2: Update node UUID

Published by evantahler almost 9 years ago

The previous version of actionhero (v12.2.1) has been pulled from NPM and replaced with this version.
A dependent package, [email protected] was pulled from NPM. This package relaxes the requirement.

actionhero - v12.2.1: WebSocket Re-Use

Published by evantahler almost 9 years ago

WebSocket Re-Use

Misc

  • Testing with node v5.x. It passes!
  • Update dependent packages to their latest versions.
  • Documentation updates
actionhero - v12.2.0: if-modified-since

Published by evantahler almost 9 years ago

Support for if-modified-since headers when serving static files

  • Allows browsers to check if the static file has changed since they last requested it, and actionhero will now respond with the proper 304 header if there is no change. Save bandwidth!
  • By @lorenzofox3 via https://github.com/evantahler/actionhero/pull/691

Misc