lib/token-cache.js
function TokenRequest(authenticate, options) {

	var self = this;
	this.status = 'expired';
	this.pendingCallbacks = [];

	// execute accumulated callbacks during the 'pending' state
	function fireCallbacks(err, token) {
		self.pendingCallbacks.forEach(function (callback) {
			callback(err, token);
		});
		self.pendingCallbacks = [];
	}

	TokenRequest.prototype.get = function (callback) {

		if (this.status == 'expired') {

			this.status = 'pending';
			this.pendingCallbacks.push(callback);

			authenticate(options, function (err, token) {
				if (err) {
					self.status = 'expired';
					return fireCallbacks(err, null);
				}
				self.issued = Date.now();
				self.duration = options.expiration || 60 * 60 * 1000;
				self.token = token;
				self.status = 'completed';
				return fireCallbacks(null, token);
			});

		} else if (this.status == 'pending') {
			// wait for the pending request instead of issuing a new one
			this.pendingCallbacks.push(callback);
		} else if (this.status == 'completed') {

			if (this.issued + this.duration < Date.now()) {
				this.status = 'expired';
				debug('token is expired, a new token will be requested');
				this.get(callback);
			} else {
				callback(null, this.token);
			}

		}
	};
}
function TokenRequest(authenticate, options) {

	var self = this;
	this.status = 'expired';
	this.pendingCallbacks = [];

	// execute accumulated callbacks during the 'pending' state
	function fireCallbacks(err, token) {
		self.pendingCallbacks.forEach(function (callback) {
			callback(err, token);
		});
		self.pendingCallbacks = [];
	}

	TokenRequest.prototype.get = function (callback) {

		if (this.status == 'expired') {

			this.status = 'pending';
			this.pendingCallbacks.push(callback);

			authenticate(options, function (err, token) {
				if (err) {
					self.status = 'expired';
					return fireCallbacks(err, null);
				}
				self.issued = Date.now();
				self.duration = options.expiration || 60 * 60 * 1000;
				self.token = token;
				self.status = 'completed';
				return fireCallbacks(null, token);
			});

		} else if (this.status == 'pending') {
			// wait for the pending request instead of issuing a new one
			this.pendingCallbacks.push(callback);
		} else if (this.status == 'completed') {

			if (this.issued + this.duration < Date.now()) {
				this.status = 'expired';
				debug('token is expired, a new token will be requested');
				this.get(callback);
			} else {
				callback(null, this.token);
			}

		}
	};
}
function TokenRequest ( authenticate , options ) { var self = this ; this . status = 'expired' ; this . pendingCallbacks = [ ] ; // execute accumulated callbacks during the 'pending' state function fireCallbacks ( err , token ) { self . pendingCallbacks . forEach ( function ( callback ) { callback ( err , token ) ; } ) ; self . pendingCallbacks = [ ] ; } TokenRequest . prototype . get = function ( callback ) { if ( this . status == 'expired' ) { this . status = 'pending' ; this . pendingCallbacks . push ( callback ) ; authenticate ( options , function ( err , token ) { if ( err ) { self . status = 'expired' ; return fireCallbacks ( err , null ) ; } self . issued = Date . now ( ) ; self . duration = options . expiration || 60 * 60 * 1000 ; self . token = token ; self . status = 'completed' ; return fireCallbacks ( null , token ) ; } ) ; } else if ( this . status == 'pending' ) { // wait for the pending request instead of issuing a new one this . pendingCallbacks . push ( callback ) ; } else if ( this . status == 'completed' ) { if ( this . issued + this . duration < Date . now ( ) ) { this . status = 'expired' ; debug ( 'token is expired, a new token will be requested' ) ; this . get ( callback ) ; } else { callback ( null , this . token ) ; } } } ; }
A single cacheable token request with support for concurrency.
@private
@constructor
A single cacheable token request with support for concurrency .