Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[minor] Added a small async iterator to handle multiple origin servers

  • Loading branch information...
commit d3c297b3c1dfb97ed176146ced7d1f75c0060487 1 parent c962d5d
@3rd-Eden authored
Showing with 98 additions and 7 deletions.
  1. +75 −0 async.js
  2. +8 −0 index.js
  3. +15 −7 lib/pull.js
View
75 async.js
@@ -0,0 +1,75 @@
+'use strict';
+
+function noop() {}
+
+/**
+ * Return the fastest result, ignoring errors.
+ *
+ * @param {Array} collection
+ * @param {Function} iterator
+ * @param {Mixed} context
+ * @param {Function} callback
+ * @api public
+ */
+exports.fastest = function fastest(collection, iterator) {
+ var callback, context, failure
+ , length = collection.length
+ , completed = 0;
+
+ if (arguments.length === 4) {
+ context = arguments[2];
+ callback = arguments[3];
+ } else {
+ callback = arguments[2];
+ }
+
+ callback = callback || noop;
+
+ collection.forEach(function forEach(item) {
+ iterator.call(context, item, function iterating(err) {
+ if (!err) {
+ callback.apply(context, arguments);
+ callback = noop;
+ }
+
+ if (++completed === length) {
+ callback.call(context);
+ }
+ });
+ });
+};
+
+/**
+ * Keep iterating over the array in series until we find a response without an
+ * error.
+ *
+ * @param {Array} collection
+ * @param {Function} iterator
+ * @param {Mixed} context
+ * @param {Function} callback
+ * @api public
+ */
+exports.failover = function failover(collection, iterator, complete) {
+ var callback, context, failure
+ , length = collection.length
+ , completed = 0;
+
+ if (arguments.length === 4) {
+ context = arguments[2];
+ callback = arguments[3];
+ } else {
+ callback = arguments[2];
+ }
+
+ callback = callback || noop;
+
+ (function series() {
+ if (!collection.length) return callback.call(context);
+
+ iterator.call(context, collection.shift(), function iterator(err) {
+ if (!err) return callback.apply(context, arguments);
+
+ process.nextTick(series);
+ });
+ })();
+};
View
8 index.js
@@ -56,6 +56,14 @@ Versions.prototype.__proto__ = EventEmitter.prototype;
Versions.prototype.version = require('./package.json').version;
/**
+ * Async helper.
+ *
+ * @type {Object}
+ * @api public
+ */
+Versions.prototype.async = require('./async');
+
+/**
* Duration conversion parser.
*
* @param {String} ms The string that needs to be parsed
View
22 lib/pull.js
@@ -8,19 +8,27 @@ var request = require('request');
* Pull resources from the remote origin servers and cache them internally.
*/
module.exports = function pull(req, res, next) {
- var cache = this.cache
+ var urls = this.get('origin servers')
+ , cache = this.cache
, self = this;
// This isn't a valid file, so don't fetch it from the server.
if (!this.allows('extension', req)) return next();
- if (!this.get('origin servers').length) return next();
+ if (!urls.length) return next();
+
+ urls = urls.map(function map(origin) {
+ return origin.url + req.url;
+ });
this.metrics.incr('origin server pull');
- request({
- uri: this.get('origin servers')[0].url + req.url,
- encoding: null // FUUUUUUUUUUUUUUUU for utf-8 as default >_<
- }, function requested(err, origin, body) {
- if (err || origin.statusCode !== 200) return next();
+ this.async.fastest(urls, function run(url, cb) {
+ // FUUUUUUUUUUUUUUUU for utf-8 as default >_<, we need to set encoding to
+ // null in order for request to spit out a Buffer instance a body
+ request.get({ uri: url, encoding: null }, cb);
+ }, function done(err, origin, body) {
+ if (err || !origin || origin.statusCode !== 200) {
+ return next();
+ }
var data = Object.create(null);
Please sign in to comment.
Something went wrong with that request. Please try again.