upgraded redis

This commit is contained in:
Manuel Astudillo
2016-02-06 19:14:49 +01:00
parent d0116be186
commit 2fdc232d4f
9 changed files with 511 additions and 1 deletions
+1
View File
@@ -0,0 +1 @@
node_modules
+32
View File
@@ -0,0 +1,32 @@
"use strict";
var Queue = require('./');
var videoQueue = Queue('video transcoding', 6379, '127.0.0.1');
videoQueue.process(function(job, done){
console.log('video job %d started.', job.jobId);
done();
});
videoQueue.on('completed', function(job) {
console.log('video job %d completed.', job.jobId);
});
videoQueue.add({video: 'http://example.com/video1.mov'});
videoQueue.add({video: 'http://example.com/video1.mov'});
videoQueue.add({video: 'http://example.com/video1.mov'});
/**
*
* Tasks
*
*/
queue.task('video', opts, function(input, next){
output = do_something_with_input(input);
next('postprocess', output);
});
+50
View File
@@ -0,0 +1,50 @@
// Generated by CoffeeScript 1.9.3
(function() {
var Q, app, bull, co, credentials, fs, matador, queue, redisDBNumber, redisHost, redisPass, redisPort, sleep;
fs = require('fs');
bull = require('./index');
queue = bull('test');
var i, j, job, k, l, m;
for (i = k = 0; k < 100; i = ++k) {
queue.add({}, { delay: 10000 }).then(function(job) {
console.log("Job " + job.jobId + " scheduled");
});
}
for (i = l = 0; l < 10; i = ++l) {
for (j = m = 0; m < 10; j = ++m) {
queue.add({}, { delay: 8000 }).then(function(job) {
console.log("Job " + job.jobId + " scheduled");
});
}
}
}).call(this);
// Generated by CoffeeScript 1.9.3
(function() {
var bull, queue;
bull = require('./index');
queue = bull('test');
queue.process(function(job, done) {
console.log("Job " + job.jobId + " is processed!");
done();
});
queue.on('error', function(err) {
console.log(err);
});
setInterval(function() {
console.log('pub');
queue.client.publishAsync(queue.toKey('delayed'), Date.now() - 1000);
}, 100);
}).call(this);
+31
View File
@@ -0,0 +1,31 @@
"use strict"
var
Queue = require('./queue'),
cluster = require('cluster');
var numWorkers = 8;
var queue = Queue("test concurrent queue", 6379, '127.0.0.1');
if(cluster.isMaster){
for (var i = 0; i < numWorkers; i++) {
cluster.fork();
}
cluster.on('online', function(worker) {
// Lets create a few jobs for every created worker
for(var i=0; i<500; i++){
queue.add({foo: 'bar'});
};
});
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
}else{
queue.process(function(job, jobDone){
console.log("Job done by worker", cluster.worker.id, job.jobId);
jobDone();
});
}
+125
View File
@@ -0,0 +1,125 @@
"use strict";
var redis = require('redis');
var when = require('when');
/**
interface JobOptions
{
attempts: number;
}
*/
// queue: Queue, msgId: string, data: {}, opts: JobOptions
var Message = function Message(queue, msgId, data, opts){
this.queue = queue;
this.msgId = msgId;
this.data = data;
this.opts = opts;
this._progress = 0;
}
Message.create = function(queue, msgId, data, opts){
var deferred = when.defer();
var msg = new Message(queue, msgId, data, opts);
queue.client.HMSET(queue.toKey(msgId), msg.toData(), function(err){
if(err){
deferred.reject(err);
}else{
deferred.resolve(job);
}
});
return deferred.promise;
}
Message.fromId = function(queue, msgId){
var deferred = when.defer();
queue.client.HGETALL(queue.toKey(msgId), function(err, data){
if(data){
deferred.resolve(Message.fromData(queue, msgId, data));
}else{
deferred.reject(err);
}
});
return deferred.promise;
}
Message.prototype.toData = function(){
return {
name: this.name,
data: JSON.stringify(this.data || {}),
opts: JSON.stringify(this.opts || {}),
progress: this._progress
}
}
Message.prototype.progress = function(progress){
if(progress){
var deferred = when.defer();
var _this = this;
this.queue.client.hset(this.queue.toKey(this.msgId), 'progress', progress, function(err){
if(err){
deferred.reject(err);
}else{
deferred.resolve();
_this.queue.emit('progress', _this, progress);
}
});
return deferred.promise;
}else{
return this._progress;
}
}
Job.prototype.completed = function(){
return this._done('completed');
}
Job.prototype.failed = function(err){
return this._done('failed');
}
Job.prototype.isCompleted = function(){
return this._isDone('completed');
}
Job.prototype.isFailed = function(){
return this._isDone('failed');
}
Job.prototype._isDone = function(list){
var deferred = when.defer();
this.queue.client.SISMEMBER(this.queue.toKey(list), this.jobId, function(err, isMember){
if(err){
deferred.reject(err);
}else{
deferred.resolve(isMember === 1);
}
});
return deferred.promise;
}
Job.prototype._done = function(list){
var deferred = when.defer();
var queue = this.queue;
var activeList = queue.toKey('active');
var completedList = queue.toKey(list);
queue.client.multi()
.lrem(activeList, 0, this.jobId)
.sadd(completedList, this.jobId)
.exec(function(err){
!err && deferred.resolve();
err && deferred.reject(err);
});
return deferred.promise;
}
/**
*/
Job.fromData = function(queue, jobId, data){
var job = new Job(queue, jobId, data.name, JSON.parse(data.data), data.opts);
job._progress = parseInt(data.progress);
return job;
}
module.exports = Job;
+57
View File
@@ -0,0 +1,57 @@
/**
* Includes all the scripts needed by the queue and jobs.
*
*
*/
/*eslint-env node */
/*global Promise:true */
'use strict';
var cache = {};
function execScript(client, hash, script){
var sha = cache[hash];
var args;
var cached = Promise.resolved(sha);
if(!sha){
cached = cacheScript(client, hash, script);
}
cached.then(function(sha){
args.shift(sha);
return client.evalshaAsync.apply(client, args).catch(function(err){
// if ERR is that script is missing we need to re-cache and test again.
// delete cache[hash];
// return execScript(client, hash, script)
})
});
}
function cacheScript(client, hash, script){
return client.scriptAsync('LOAD', script).then(function(sha){
cache[hash] = sha;
return sha;
})
}
var scripts = {
isJobInList: function(client, listKey, jobId){
var script = [
'local function item_in_list (list, item)',
' for _, v in pairs(list) do',
' if v == item then',
' return 1',
' end',
' end',
' return nil',
'end',
'local items = redis.call("LRANGE", KEYS[1], 0, -1)',
'return item_in_list(items, ARGV[1])'
].join('\n');
return scripts._execScript(client, 'isJobInList', 1, listKey, jobId).then(function(result){
return result === 1;
});
}
}
module.exports.scripts = scripts;
+48
View File
@@ -0,0 +1,48 @@
/**
State machine.
Distributed state machine.
*/
var machine = Machine('signup', opts); // opts -> redis connection mostly, name of the machine.
machine.state('send mail', function(data, next){
// In this state we send an email with a confirmation link and exit the state
next('wait confirmation', data);
});
machine.state('wait confirmation'); // // In this state we do nothing we just wait for an external input
machine.state('confirm user', function(task){
return data;
})
machine.next('wait confirmation', data);
/**
queue('wait confirmation').add(data);
*/
machine.state('transcode video', function(data){
// transcode...
this.next('append moov');
}).catch(function(err){
this.next('delete tmp');
});
machine.state('append moov', input, function(data, next){
// Append MOOV etc.
this.next('delete tmp');
});
machine.next('delete temp', input, function(data, next){
// delete temp file
this.next('update user account');
});
machine.state('update user account', function(data, next){
// update database
});
+1 -1
View File
@@ -20,7 +20,7 @@
"bluebird": "^2.10.2",
"lodash": "^3.10.1",
"node-uuid": "^1.4.7",
"redis": "^0.12.1",
"redis": "^2.4.2",
"semver": "^4.2.0"
},
"devDependencies": {
+166
View File
@@ -0,0 +1,166 @@
// Type definitions for mocha 2.0.1
// Project: http://mochajs.org/
// Definitions by: Kazi Manzur Rashid <https://github.com/kazimanzurrashid/>, otiai10 <https://github.com/otiai10>, jt000 <https://github.com/jt000>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
interface Mocha {
// Setup mocha with the given setting options.
setup(options: MochaSetupOptions): Mocha;
//Run tests and invoke `fn()` when complete.
run(callback?: () => void): void;
// Set reporter as function
reporter(reporter: () => void): Mocha;
// Set reporter, defaults to "dot"
reporter(reporter: string): Mocha;
// Enable growl support.
growl(): Mocha
}
interface MochaSetupOptions {
//milliseconds to wait before considering a test slow
slow?: number;
// timeout in milliseconds
timeout?: number;
// ui name "bdd", "tdd", "exports" etc
ui?: string;
//array of accepted globals
globals?: any[];
// reporter instance (function or string), defaults to `mocha.reporters.Dot`
reporter?: any;
// bail on the first test failure
bail?: boolean;
// ignore global leaks
ignoreLeaks?: boolean;
// grep string or regexp to filter tests with
grep?: any;
}
interface MochaDone {
(error?: Error): void;
}
declare var mocha: Mocha;
declare var describe: {
(description: string, spec: () => void): void;
only(description: string, spec: () => void): void;
skip(description: string, spec: () => void): void;
timeout(ms: number): void;
}
// alias for `describe`
declare var context: {
(contextTitle: string, spec: () => void): void;
only(contextTitle: string, spec: () => void): void;
skip(contextTitle: string, spec: () => void): void;
timeout(ms: number): void;
};
// alias for `describe`
declare var suite: {
(suiteTitle: string, spec: () => void): void;
only(suiteTitle: string, spec: () => void): void;
skip(suiteTitle: string, spec: () => void): void;
timeout(ms: number): void;
};
declare var it: {
(expectation: string, assertion?: () => void): void;
(expectation: string, assertion?: (done: MochaDone) => void): void;
only(expectation: string, assertion?: () => void): void;
only(expectation: string, assertion?: (done: MochaDone) => void): void;
skip(expectation: string, assertion?: () => void): void;
skip(expectation: string, assertion?: (done: MochaDone) => void): void;
timeout(ms: number): void;
};
// alias for `it`
declare var test: {
(expectation: string, assertion?: () => void): void;
(expectation: string, assertion?: (done: MochaDone) => void): void;
only(expectation: string, assertion?: () => void): void;
only(expectation: string, assertion?: (done: MochaDone) => void): void;
skip(expectation: string, assertion?: () => void): void;
skip(expectation: string, assertion?: (done: MochaDone) => void): void;
timeout(ms: number): void;
};
declare function before(action: () => void): void;
declare function before(action: (done: MochaDone) => void): void;
declare function setup(action: () => void): void;
declare function setup(action: (done: MochaDone) => void): void;
declare function after(action: () => void): void;
declare function after(action: (done: MochaDone) => void): void;
declare function teardown(action: () => void): void;
declare function teardown(action: (done: MochaDone) => void): void;
declare function beforeEach(action: () => void): void;
declare function beforeEach(action: (done: MochaDone) => void): void;
declare function suiteSetup(action: () => void): void;
declare function suiteSetup(action: (done: MochaDone) => void): void;
declare function afterEach(action: () => void): void;
declare function afterEach(action: (done: MochaDone) => void): void;
declare function suiteTeardown(action: () => void): void;
declare function suiteTeardown(action: (done: MochaDone) => void): void;
declare module "mocha" {
class Mocha {
constructor(options?: {
grep?: RegExp;
ui?: string;
reporter?: string;
timeout?: number;
bail?: boolean;
});
bail(value?: boolean): Mocha;
addFile(file: string): Mocha;
reporter(value: string): Mocha;
ui(value: string): Mocha;
grep(value: string): Mocha;
grep(value: RegExp): Mocha;
invert(): Mocha;
ignoreLeaks(value: boolean): Mocha;
checkLeaks(): Mocha;
growl(): Mocha;
globals(value: string): Mocha;
globals(values: string[]): Mocha;
useColors(value: boolean): Mocha;
useInlineDiffs(value: boolean): Mocha;
timeout(value: number): Mocha;
slow(value: number): Mocha;
enableTimeouts(value: boolean): Mocha;
asyncOnly(value: boolean): Mocha;
noHighlighting(value: boolean): Mocha;
run(onComplete?: (failures: number) => void): void;
}
export = Mocha;
}