Skip to content

Commit

Permalink
full initial implementation 💩
Browse files Browse the repository at this point in the history
an initial implementation of Ponos!
  • Loading branch information
Bryan Kendall committed Sep 18, 2015
1 parent 2dde400 commit 0894525
Show file tree
Hide file tree
Showing 18 changed files with 758 additions and 37 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
@@ -0,0 +1,2 @@
node_modules
coverage
50 changes: 50 additions & 0 deletions .eslintrc
@@ -0,0 +1,50 @@
env:
node: true
mocha: true

rules:
array-bracket-spacing: [2, "always", { "singleValue": false }]
block-scoped-var: 2
brace-style: [2, "1tbs", { "allowSingleLine": true }]
camelcase: 2
comma-dangle: [2, "never"]
comma-style: 2
computed-property-spacing: 2
consistent-this: [1, "self"]
dot-notation: 2
eol-last: 2
eqeqeq: 2
indent: [2, 2]
key-spacing: 2
max-len: [2, 80, 4]
new-cap: 2
no-array-constructor: 2
no-dupe-keys: 2
no-eq-null: 2
no-extra-boolean-cast: 2
no-extra-parens: [2, "functions"]
no-irregular-whitespace: 2
no-multi-spaces: 2
no-multi-str: 2
no-new-object: 2
no-shadow-restricted-names: 2
no-spaced-func: 2
no-trailing-spaces: 2
no-underscore-dangle: 0
no-unused-vars: 2
no-use-before-define: [2, "nofunc"]
object-curly-spacing: [2, "always"]
one-var: [2, "never"]
padded-blocks: [2, "never"]
quote-props: [2, "as-needed"]
quotes: [2, "single"]
semi-spacing: 2
semi: [2, always]
space-after-keywords: 2
space-before-blocks: 2
space-before-function-paren: [2, "always"]
space-infix-ops: 2
spaced-comment: 2
strict: [2, "global"]
use-isnan: 2
valid-jsdoc: [2, {"requireReturn": false}]
3 changes: 2 additions & 1 deletion .gitignore
@@ -1,3 +1,4 @@
node_modules/
.DS_Store

coverage
npm-debug.log
6 changes: 6 additions & 0 deletions .istanbul.yml
@@ -0,0 +1,6 @@
check:
global:
statements: 100
lines: 100
branches: 100
functions: 100
13 changes: 13 additions & 0 deletions .travis.yml
@@ -0,0 +1,13 @@
language: node_js
node_js:
- "0.10"
- "0.12"
- "4"
sudo: false
env:
- LOG_LEVEL_STDOUT=error
script:
- npm run lint
- npm run coverage
after_success:
- npm run coverage-check
11 changes: 11 additions & 0 deletions index.js
@@ -0,0 +1,11 @@
'use strict';

var Server = require('./lib/server');

module.exports = {
server: function (opts) { return new Server(opts); },
// Errors:
TaskError: require('./lib/errors/task-error'),
TaskFatalError: require('./lib/errors/task-fatal-error'),
TaskMaxRetriesError: require('./lib/errors/task-max-retries-error')
};
30 changes: 30 additions & 0 deletions lib/error.js
@@ -0,0 +1,30 @@
'use strict';

var util = require('util');
var ErrorCat = require('error-cat');
var log = require('./logger');

/**
* Custom ErrorCat error handler.
* @class
*/
function PonosError () {
ErrorCat.apply(this, arguments);
}
util.inherits(PonosError, ErrorCat);

/**
* Logs errors via default ponos logger.
* @param {error} err PonosError to log.
* @see error-cat
*/
PonosError.prototype.log = function (err) {
log.error({ err: err }, err.message);
};

/**
* PonosError handling via error-cat.
* @module ponos:error
* @author Ryan Sandor Richards
*/
module.exports = new PonosError();
44 changes: 44 additions & 0 deletions lib/errors/task-error.js
@@ -0,0 +1,44 @@
'use strict';

var util = require('util');
var defaults = require('101/defaults');
var isObject = require('101/is-object');

/**
* Error type for task rejection promises that indicated to the worker that
* something went wrong, but that it should attempt the task again. Useful for
* handling any sort of issue that may have a temporal component (network
* connectivity, etc.)
* @class
* @param {string} queue Name of the queue that encountered the error.
* @param {string} message Message for the task error.
* @param {object} [data] Extra data to include with the error, optional.
*/
function TaskError (queue, message, data) {
Error.call(this);
this.setMessageAndData(queue, message, data);
}
util.inherits(TaskError, Error);

/**
* Sets the message and data for the error. This abstraction makes it easy to
* test that subclasses are being initialized correctly.
* @param {string} queue Name of the queue that encountered the error.
* @param {string} message Message for the task error.
* @param {object} [data] Extra data to include with the error, optional.
*/
TaskError.prototype.setMessageAndData = function (queue, message, data) {
this.message = queue + ': ' + message;
var errorData = { queue: queue };
if (isObject(data)) {
defaults(errorData, data);
}
this.data = errorData;
};

/**
* Normal error for tasks that indicates the job should be tried again.
* @author Ryan Sandor Richards
* @module ponos:errors
*/
module.exports = TaskError;
25 changes: 25 additions & 0 deletions lib/errors/task-fatal-error.js
@@ -0,0 +1,25 @@
'use strict';

var util = require('util');
var TaskError = require('./task-error');

/**
* Error type for tasks that indicate a job cannot be fulfilled. When workers
* encounter this type of error they should immediately stop trying to fulfill
* a job via the task.
* @class
* @param {string} queue Name of the queue that encountered the error.
* @param {string} message Message for the error.
* @param {object} [data] Additional data for the error, optional.
*/
function TaskFatalError (queue, message, data) {
TaskError.call(this, queue, message, data);
}
util.inherits(TaskFatalError, TaskError);

/**
* Fatal error that indicates a job should be abandoned.
* @author Ryan Sandor Richards
* @module ponos:errors
*/
module.exports = TaskFatalError;
18 changes: 18 additions & 0 deletions lib/errors/task-max-retries-error.js
@@ -0,0 +1,18 @@
'use strict';

var util = require('util');
var TaskError = require('./task-error');

function TaskMaxRetriesError (queue, data) {
var message = 'Worker max retries reached';
TaskError.call(this, queue, message, data);
}
util.inherits(TaskMaxRetriesError, TaskError);

/**
* Error that indicates that the max retries have been reached. Mostly for
* internal usage.
* @author Bryan Kendall
* @module ponos:errors
*/
module.exports = TaskMaxRetriesError;
43 changes: 43 additions & 0 deletions lib/logger.js
@@ -0,0 +1,43 @@
'use strict';

// var exists = require('101/exists');
// var isObject = require('101/is-object');
var bunyan = require('bunyan');
// var Bunyan2Loggly = require('bunyan-loggly').Bunyan2Loggly;

/**
* Bunyan logger for ponos.
* @author Bryan Kendall
* @module ponos:logger
*/
module.exports = bunyan.createLogger({
name: 'ponos',
streams: getStreams()
});

// Expose get streams for unit testing
module.exports.getStreams = getStreams;

/**
* Streams for ponos's bunyan logger.
* @return {array} An array of streams for the bunyan logger
*/
function getStreams () {
var streams = [{
level: process.env.LOG_LEVEL_STDOUT,
stream: process.stdout
}];

// if (exists(process.env.LOGGLY_TOKEN)) {
// streams.push({
// level: 'trace',
// stream: new Bunyan2Loggly({
// token: process.env.LOGGLY_TOKEN,
// subdomain: 'sandboxes'
// }, process.env.BUNYAN_BATCH_LOG_COUNT),
// type: 'raw'
// });
// }

return streams;
}

0 comments on commit 0894525

Please sign in to comment.