Comparing version 0.3.0 to 0.4.0
var Benchmark = require('benchmark').Benchmark; | ||
var suite = new Benchmark.Suite; | ||
Candle = require('..').Candle; | ||
Candle = require('..'); | ||
@@ -5,0 +5,0 @@ //function noop() {}; |
/*jslint indent: 4 */ | ||
var timers = require('./timers.js'); | ||
"use strict"; | ||
//var timers = require('timers'); | ||
var timers = require('./timers.js'); // use optimized version of node's timers.js | ||
var util = require('util'); | ||
var debug = require('debug')('candle'); | ||
var TimeoutError = function () {}; | ||
var Timeout = function () {}; | ||
var TimeoutError = function () { | ||
Error.captureStackTrace(this, TimeoutError); | ||
}; | ||
util.inherits(TimeoutError, Error); | ||
TimeoutError.prototype.name = 'TimeoutError'; | ||
var Candle = function () { | ||
"use strict"; | ||
this.callbacks = Object.create(null); | ||
@@ -16,3 +23,2 @@ this.id = 0; | ||
Candle.prototype.add = function (callback) { | ||
"use strict"; | ||
var id = ++this.id; | ||
@@ -24,3 +30,2 @@ debug('add(...), assigned id = ' + id); | ||
Candle.prototype.resolve = function (id, err, result) { | ||
"use strict"; | ||
debug('resolve(' + id + ', ...)'); | ||
@@ -44,3 +49,2 @@ var l = arguments.length, callback = this.callbacks[id], i, args; | ||
Candle.prototype.remove = function (id) { | ||
"use strict"; | ||
debug('remove(' + id + ')'); | ||
@@ -51,3 +55,2 @@ this.clearTimeout(id); | ||
Candle.prototype.setTimeout = function (id, timeout) { | ||
"use strict"; | ||
debug('setTimeout(' + id + ')'); | ||
@@ -59,3 +62,2 @@ if (!this.callbacks[id]) { return; } | ||
Candle.prototype.clearTimeout = function (id) { | ||
"use strict"; | ||
debug('clearTimeout(' + id + ')'); | ||
@@ -68,3 +70,2 @@ if (this.callbacks[id] && this.callbacks[id][1]) { | ||
Candle.prototype.getTimeout = function (id) { | ||
"use strict"; | ||
var self = this; | ||
@@ -74,3 +75,2 @@ return function () { return self.onTimeout(id); }; | ||
Candle.prototype.onTimeout = function (id) { | ||
"use strict"; | ||
debug('onTimeout(' + id + ')'); | ||
@@ -80,19 +80,15 @@ if (typeof this.timeoutResolver === 'function') { | ||
} else { | ||
this.resolve(id, new TimeoutError()); | ||
this.resolve(id, new Timeout()); | ||
} | ||
}; | ||
Candle.prototype.setTimeoutResolver = function (callback) { | ||
"use strict"; | ||
this.timeoutResolver = callback; | ||
}; | ||
Candle.prototype.isTimeoutError = function (obj) { | ||
"use strict"; | ||
return obj instanceof TimeoutError; | ||
}; | ||
module.exports.Candle = Candle; | ||
var create = function () { | ||
"use strict"; | ||
return new Candle(); | ||
}; | ||
module.exports.create = create; | ||
module.exports = Candle; | ||
module.exports.create = create; | ||
module.exports.Timeout = Timeout; | ||
module.exports.TimeoutError = TimeoutError; |
@@ -1,2 +0,2 @@ | ||
var Candle = require('..').Candle; | ||
var Candle = require('..'); | ||
@@ -3,0 +3,0 @@ // Create a new candle, usually you will need only one since it can handle many callbacks. |
@@ -0,33 +1,66 @@ | ||
// This example emulates cluster environment with 4 servers. | ||
// Server #1 has open 'sockets' to #2, #3, #4 which respond in (60, 90 and 120 ms correspondingly) | ||
// Server #1 has a shard map and a map of opened sockets. | ||
// Then it sends a distributed request according to the shard map. Each server responds with a delay. | ||
// It passes a payload containing its origin server number. | ||
// Since the server1 sets a timeout of 100ms, then no replies from the server4 (where delay is 120ms) | ||
// will be included into results. | ||
// socket imitation compatible with socket.io :) | ||
var socket = new (require('events').EventEmitter); | ||
var EventEmitter = require('events').EventEmitter; | ||
// server2 | ||
socket.on('myrequest', function(id, payload) { | ||
// dont send anything at all about 'r3' | ||
if (payload == 'r3') return; | ||
// server2, server3, server4 | ||
var sockets = {}; | ||
for (var i = 2; i < 5; i++) { | ||
(function (i) { | ||
sockets[i] = new EventEmitter; | ||
sockets[i].on('myrequest', function(id, payload) { | ||
// send request with delay dependent on server id: 0 for server#0, | ||
setTimeout(function() { | ||
sockets[i].emit('myresponse', id, payload + '_response_from_server#' + i); | ||
}, i * 30); | ||
}); | ||
})(i); | ||
} | ||
// send response after 10ms for 'r1', but after 1000ms for 'r2'. | ||
var timeout = (payload == 'r1') ? 10 : 1000; | ||
setTimeout(function() { | ||
socket.emit('myresponse', id, payload + '_response'); | ||
}, timeout); | ||
}); | ||
// server1 | ||
var Candle = require('..').Candle; | ||
var Candle = require('..'); | ||
var c = new Candle(); | ||
var start = Date.now(); | ||
socket.on('myresponse', function(id, response) { | ||
c.resolve(id, null, response); | ||
}); | ||
function distributed_request (requests, gather) { | ||
var responses = []; | ||
for (var i in sockets) { | ||
sockets[i].on('myresponse', function(id, response) { | ||
c.resolve(id, null, response); | ||
}); | ||
} | ||
// shard map | ||
var shard_map = { | ||
r1: 2, | ||
r2: 3, | ||
r3: 4, | ||
r4: 2, | ||
r5: 4 | ||
}; | ||
// collector is an utility for collecting responses. Since it has collected the target number of collectibles, it | ||
// calls the handler function passing the collection to it. | ||
function collector (n, handle) { | ||
var collected = []; | ||
if (n == 0) handle(collected); | ||
return function (err, response) { | ||
collected.push(response); | ||
if (collected.length == n) { | ||
handle(collected); | ||
} | ||
} | ||
} | ||
function distributed_request (requests, handle) { | ||
// create a collector | ||
var collect = collector(requests.length, handle); | ||
for (var i in requests) { | ||
var id = c.add(function(err, response) { | ||
responses.push(response); | ||
if (responses.length == requests.length) { | ||
gather(responses); | ||
} | ||
}); | ||
// register a callback | ||
var id = c.add(collect); | ||
// set a timeout to it | ||
c.setTimeout(id, 100); | ||
// map key -> shard -> socket | ||
var socket = sockets[shard_map[requests[i]]]; | ||
// send a request | ||
socket.emit('myrequest', id, requests[i]); | ||
@@ -39,2 +72,4 @@ } | ||
} | ||
distributed_request(['r1', 'r2', 'r3'], handle_responses); | ||
distributed_request(['r1', 'r2', 'r3', 'r4', 'r5'], handle_responses); | ||
distributed_request(['r1', 'r2'], handle_responses); | ||
distributed_request(['r1', 'r4'], handle_responses); |
@@ -17,3 +17,3 @@ // socket imitation compatible with socket.io :) | ||
// server1 | ||
var Candle = require('..').Candle; | ||
var Candle = require('..'); | ||
var c = new Candle(); | ||
@@ -25,3 +25,3 @@ var start = Date.now(); | ||
var doSmthWithRequest = function(err, request) { | ||
console.log('got', err, request, 'on', (Date.now() - start) + 'th ms'); | ||
console.log('got', !!err, request, 'on', (Date.now() - start) + 'th ms'); | ||
}; | ||
@@ -28,0 +28,0 @@ var id; |
@@ -1,2 +0,2 @@ | ||
var Candle = require('..').Candle; | ||
var Candle = require('..'); | ||
@@ -7,3 +7,3 @@ // Create a new candle, usually you will need only one since it can handle many callbacks. | ||
// Add a callback to it | ||
var id = c.add(function(err, response) { console.log('callback fired,', err, response); }) | ||
var id = c.add(function(err, response) { console.log('callback fired,', !!err, response); }) | ||
@@ -10,0 +10,0 @@ c.setTimeout(id, 1000); |
@@ -1,2 +0,2 @@ | ||
var Candle = require('..').Candle; | ||
var Candle = require('..'); | ||
@@ -7,3 +7,3 @@ // Create a new candle, usually you will need only one since it can handle many callbacks. | ||
// Add a callback to it | ||
var id = c.add(function(err, response) { console.log('callback fired,', response); }) | ||
var id = c.add(function(err, response) { console.log('callback fired,', !!err, response); }) | ||
@@ -10,0 +10,0 @@ // You can pass these ids over network and catch back along it with a response. |
@@ -1,6 +0,6 @@ | ||
var Candle = require('..').Candle; | ||
var Candle = require('..'); | ||
var c = new Candle(), id; | ||
id = c.add(function(err, result) { console.log('cb1', err, result); }); | ||
id = c.add(function(err, result) { console.log('cb1', !!err, result); }); | ||
c.setTimeout(id, 100); | ||
@@ -10,7 +10,7 @@ setTimeout(c.resolve.bind(c, id, null, 'result1.1'), 50); | ||
id = c.add(function(err, result) { console.log('cb2', err, result); }); | ||
id = c.add(function(err, result) { console.log('cb2', !!err, result); }); | ||
c.setTimeout(id, 100); | ||
setTimeout(c.resolve.bind(c, id, null, 'result2'), 150); | ||
id = c.add(function(err, result) { console.log('cb3', err, result); }); | ||
id = c.add(function(err, result) { console.log('cb3', !!err, result); }); | ||
c.setTimeout(id, 100); |
{ | ||
"name": "candle", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "A module for weak referenced callbacks with timeouts.", | ||
@@ -5,0 +5,0 @@ "main": "candle.js", |
@@ -19,3 +19,3 @@ node-candle | ||
```javascript | ||
var Candle = require('candle').Candle; | ||
var Candle = require('candle'); | ||
@@ -26,3 +26,3 @@ // Create a new candle, usually you will need only one since it can handle many callbacks. | ||
// Add a callback to it | ||
var id = c.add(function(err, response) { console.log('callback fired,', response); }) | ||
var id = c.add(function(err, response) { console.log('callback fired,', !!err, response); }) | ||
@@ -33,3 +33,3 @@ // You can pass these ids over network and catch back along it with a response. | ||
// output: "callback fired, whoa!" | ||
// output: "callback fired, false whoa!" | ||
``` | ||
@@ -56,3 +56,3 @@ <a href="https://github.com/AlexeyKupershtokh/node-candle/tree/master/examples">More examples</a>. Also consider `DEBUG=candle node script.js` to better understand how it works. | ||
```javascript | ||
var Candle = require('candle').Candle; | ||
var Candle = require('candle'); | ||
@@ -66,3 +66,3 @@ var c = new Candle(); | ||
var doSmthWithRequest = function(err, request) { | ||
console.log('got', err, request, 'on', Date.now() - start, 'th ms'); | ||
console.log('got', !!err, request, 'on', Date.now() - start, 'th ms'); | ||
}; | ||
@@ -82,5 +82,5 @@ var id; | ||
``` | ||
got null r1_response on 13 th ms | ||
got timeout undefined on 102 th ms | ||
got timeout undefined on 102 th ms | ||
got false r1_response on 13 th ms | ||
got true undefined on 102 th ms | ||
got true undefined on 102 th ms | ||
``` | ||
@@ -103,3 +103,3 @@ So we get the response and 2 timeouts right after 100ms passed. | ||
* `c.clearTimeout(id)` - remove a timeout from a callback by id. | ||
* `c.setTimeoutResolver(callback)` - assign a custom candle-wide callback that will be used to resolve on timeout. Default behavior is `function(id) { this.resolve(id, 'timeout'); }`. Sometimes, e.g. when you use the candle with <a href="https://github.com/caolan/async#parallel">async.parallel</a>, you may want to use something like this callback: `function(id) { this.resolve(id, null, { status: 'timeout' }); }` to avoid it look like an error. | ||
* `c.setTimeoutResolver(callback)` - assign a custom candle-wide callback that will be used to resolve on timeout. Default behavior is `function(id) { this.resolve(id, new Timeout()); }`. Sometimes, e.g. when you use the candle with <a href="https://github.com/caolan/async#parallel">async.parallel</a>, you may want to use something like this callback: `function(id) { this.resolve(id, null, { status: 'timeout' }); }` to avoid it look like an error. | ||
@@ -106,0 +106,0 @@ Running tests |
var assert = require("assert") | ||
var Candle = require('..').Candle; | ||
var Candle = require('..'); | ||
@@ -62,3 +62,3 @@ describe('candle', function(){ | ||
var id = c.add(function(err) { | ||
assert.ok(c.isTimeoutError(err)); | ||
assert.ok(err instanceof Candle.Timeout); | ||
done(); | ||
@@ -100,3 +100,3 @@ }); | ||
describe('#setTimeoutResolver()', function(){ | ||
it('should then resolve callbacks', function(done){ | ||
it('should be used for resolving callbacks', function(done){ | ||
var c = new Candle; | ||
@@ -111,3 +111,22 @@ var id = c.add(function(err, response) { | ||
}); | ||
it('should allow using Candle.Timeout', function(done){ | ||
var c = new Candle; | ||
var id = c.add(function(err, response) { | ||
assert.ok(err instanceof Candle.Timeout); | ||
done(); | ||
}); | ||
c.setTimeoutResolver(function(id) { this.resolve(id, new Candle.Timeout()); }); | ||
c.setTimeout(id, 1); | ||
}); | ||
it('should allow using Candle.TimeoutError', function(done){ | ||
var c = new Candle; | ||
var id = c.add(function(err, response) { | ||
assert.ok(err instanceof Candle.TimeoutError); | ||
assert.ok(err instanceof Error); | ||
done(); | ||
}); | ||
c.setTimeoutResolver(function(id) { this.resolve(id, new Candle.TimeoutError()); }); | ||
c.setTimeout(id, 1); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
315550
1113