mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-31 18:37:00 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			106 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| //
 | |
| // used by properLockFile
 | |
| // Source: https://github.com/tim-kos/node-retry
 | |
| //
 | |
| 
 | |
| var RetryOperation = require('./retry_operation');
 | |
| 
 | |
| exports.operation = function (options) {
 | |
|   var timeouts = exports.timeouts(options);
 | |
|   return new RetryOperation(timeouts, {
 | |
|     forever: options && options.forever,
 | |
|     unref: options && options.unref,
 | |
|     maxRetryTime: options && options.maxRetryTime
 | |
|   });
 | |
| };
 | |
| 
 | |
| exports.timeouts = function (options) {
 | |
|   if (options instanceof Array) {
 | |
|     return [].concat(options);
 | |
|   }
 | |
| 
 | |
|   var opts = {
 | |
|     retries: 10,
 | |
|     factor: 2,
 | |
|     minTimeout: 1 * 1000,
 | |
|     maxTimeout: Infinity,
 | |
|     randomize: false
 | |
|   };
 | |
|   for (var key in options) {
 | |
|     opts[key] = options[key];
 | |
|   }
 | |
| 
 | |
|   if (opts.minTimeout > opts.maxTimeout) {
 | |
|     throw new Error('minTimeout is greater than maxTimeout');
 | |
|   }
 | |
| 
 | |
|   var timeouts = [];
 | |
|   for (var i = 0; i < opts.retries; i++) {
 | |
|     timeouts.push(this.createTimeout(i, opts));
 | |
|   }
 | |
| 
 | |
|   if (options && options.forever && !timeouts.length) {
 | |
|     timeouts.push(this.createTimeout(i, opts));
 | |
|   }
 | |
| 
 | |
|   // sort the array numerically ascending
 | |
|   timeouts.sort(function (a, b) {
 | |
|     return a - b;
 | |
|   });
 | |
| 
 | |
|   return timeouts;
 | |
| };
 | |
| 
 | |
| exports.createTimeout = function (attempt, opts) {
 | |
|   var random = (opts.randomize)
 | |
|     ? (Math.random() + 1)
 | |
|     : 1;
 | |
| 
 | |
|   var timeout = Math.round(random * opts.minTimeout * Math.pow(opts.factor, attempt));
 | |
|   timeout = Math.min(timeout, opts.maxTimeout);
 | |
| 
 | |
|   return timeout;
 | |
| };
 | |
| 
 | |
| exports.wrap = function (obj, options, methods) {
 | |
|   if (options instanceof Array) {
 | |
|     methods = options;
 | |
|     options = null;
 | |
|   }
 | |
| 
 | |
|   if (!methods) {
 | |
|     methods = [];
 | |
|     for (var key in obj) {
 | |
|       if (typeof obj[key] === 'function') {
 | |
|         methods.push(key);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (var i = 0; i < methods.length; i++) {
 | |
|     var method = methods[i];
 | |
|     var original = obj[method];
 | |
| 
 | |
|     obj[method] = function retryWrapper(original) {
 | |
|       var op = exports.operation(options);
 | |
|       var args = Array.prototype.slice.call(arguments, 1);
 | |
|       var callback = args.pop();
 | |
| 
 | |
|       args.push(function (err) {
 | |
|         if (op.retry(err)) {
 | |
|           return;
 | |
|         }
 | |
|         if (err) {
 | |
|           arguments[0] = op.mainError();
 | |
|         }
 | |
|         callback.apply(this, arguments);
 | |
|       });
 | |
| 
 | |
|       op.attempt(function () {
 | |
|         original.apply(obj, args);
 | |
|       });
 | |
|     }.bind(obj, original);
 | |
|     obj[method].options = options;
 | |
|   }
 | |
| };
 |