Skip to content

Commit

Permalink
Convert networking files to ES6.
Browse files Browse the repository at this point in the history
Issue shaka-project#1157

Change-Id: Iae83b88881b351c97e8ec020625167f5f700f97e
  • Loading branch information
TheModMaker committed May 20, 2019
1 parent 4f56bda commit 74918b9
Show file tree
Hide file tree
Showing 11 changed files with 1,068 additions and 1,077 deletions.
4 changes: 3 additions & 1 deletion build/generateExterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ function getIdentifierString(node) {
* @return {!Array.<string>} a list of the parameter names.
*/
function getFunctionParameters(node) {
assert.equal(node.type, 'FunctionExpression');
assert(node.type == 'FunctionExpression' ||
node.type == 'ArrowFunctionExpression');
// Example code: function(x, y, z = null, ...varArgs) {...}
// Example node: {
// params: [
Expand Down Expand Up @@ -489,6 +490,7 @@ function createExternAssignment(name, node) {
return classString;
}

case 'ArrowFunctionExpression':
case 'FunctionExpression': {
// Example code: foo.square = function(x) { return x * x; };
// Example node: { params: [ { type: 'Identifier', name: 'x' } ] }
Expand Down
2 changes: 1 addition & 1 deletion lib/hls/hls_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2291,7 +2291,7 @@ shaka.hls.HlsParser.widevineDrmParser_ = function(drmTag) {
}

const uri = HlsParser.getRequiredAttributeValue_(drmTag, 'URI');
const parsedData = shaka.net.DataUriPlugin.parse(uri);
const parsedData = shaka.net.DataUriPlugin.parseRaw(uri);

// The data encoded in the URI is a PSSH box to be used as init data.
const pssh = new Uint8Array(parsedData.data);
Expand Down
276 changes: 137 additions & 139 deletions lib/net/backoff.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,175 +25,173 @@ goog.require('shaka.util.Timer');
* Backoff represents delay and backoff state. This is used by NetworkingEngine
* for individual requests and by StreamingEngine to retry streaming failures.
*
* @param {shaka.extern.RetryParameters} parameters
* @param {boolean=} autoReset If true, start at a "first retry" state and
* and auto-reset that state when we reach maxAttempts.
* Default set to false.
*
* @struct
* @constructor
* @final
*/
shaka.net.Backoff = function(parameters, autoReset = false) {
// Set defaults as we unpack these, so that individual app-level requests in
// NetworkingEngine can be missing parameters.

const defaults = shaka.net.Backoff.defaultRetryParameters();

shaka.net.Backoff = class {
/**
* @const
* @private {number}
* @param {shaka.extern.RetryParameters} parameters
* @param {boolean=} autoReset If true, start at a "first retry" state and
* and auto-reset that state when we reach maxAttempts.
* Default set to false.
*/
this.maxAttempts_ = (parameters.maxAttempts == null) ?
defaults.maxAttempts : parameters.maxAttempts;
constructor(parameters, autoReset = false) {
// Set defaults as we unpack these, so that individual app-level requests in
// NetworkingEngine can be missing parameters.

goog.asserts.assert(this.maxAttempts_ >= 1, 'maxAttempts should be >= 1');
const defaults = shaka.net.Backoff.defaultRetryParameters();

/**
* @const
* @private {number}
*/
this.baseDelay_ = (parameters.baseDelay == null) ?
defaults.baseDelay : parameters.baseDelay;
/**
* @const
* @private {number}
*/
this.maxAttempts_ = (parameters.maxAttempts == null) ?
defaults.maxAttempts : parameters.maxAttempts;

goog.asserts.assert(this.baseDelay_ >= 0, 'baseDelay should be >= 0');
goog.asserts.assert(this.maxAttempts_ >= 1, 'maxAttempts should be >= 1');

/**
* @const
* @private {number}
*/
this.fuzzFactor_ = (parameters.fuzzFactor == null) ?
defaults.fuzzFactor : parameters.fuzzFactor;
/**
* @const
* @private {number}
*/
this.baseDelay_ = (parameters.baseDelay == null) ?
defaults.baseDelay : parameters.baseDelay;

goog.asserts.assert(this.fuzzFactor_ >= 0, 'fuzzFactor should be >= 0');
goog.asserts.assert(this.baseDelay_ >= 0, 'baseDelay should be >= 0');

/**
* @const
* @private {number}
*/
this.backoffFactor_ = (parameters.backoffFactor == null) ?
defaults.backoffFactor : parameters.backoffFactor;
/**
* @const
* @private {number}
*/
this.fuzzFactor_ = (parameters.fuzzFactor == null) ?
defaults.fuzzFactor : parameters.fuzzFactor;

goog.asserts.assert(this.backoffFactor_ >= 0, 'backoffFactor should be >= 0');
goog.asserts.assert(this.fuzzFactor_ >= 0, 'fuzzFactor should be >= 0');

/** @private {number} */
this.numAttempts_ = 0;
/**
* @const
* @private {number}
*/
this.backoffFactor_ = (parameters.backoffFactor == null) ?
defaults.backoffFactor : parameters.backoffFactor;

/** @private {number} */
this.nextUnfuzzedDelay_ = this.baseDelay_;
goog.asserts.assert(
this.backoffFactor_ >= 0, 'backoffFactor should be >= 0');

/** @private {boolean} */
this.autoReset_ = autoReset;
/** @private {number} */
this.numAttempts_ = 0;

if (this.autoReset_) {
// There is no delay before the first attempt. In StreamingEngine (the
// intended user of auto-reset mode), the first attempt was implied, so we
// reset numAttempts to 1. Therefore maxAttempts (which includes the first
// attempt) must be at least 2 for us to see a delay.
goog.asserts.assert(this.maxAttempts_ >= 2,
'maxAttempts must be >= 2 for autoReset == true');
this.numAttempts_ = 1;
}
};
/** @private {number} */
this.nextUnfuzzedDelay_ = this.baseDelay_;

/** @private {boolean} */
this.autoReset_ = autoReset;

/**
* @return {!Promise} Resolves when the caller may make an attempt, possibly
* after a delay. Rejects if no more attempts are allowed.
*/
shaka.net.Backoff.prototype.attempt = async function() {
if (this.numAttempts_ >= this.maxAttempts_) {
if (this.autoReset_) {
this.reset_();
} else {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.PLAYER,
shaka.util.Error.Code.ATTEMPTS_EXHAUSTED);
// There is no delay before the first attempt. In StreamingEngine (the
// intended user of auto-reset mode), the first attempt was implied, so we
// reset numAttempts to 1. Therefore maxAttempts (which includes the
// first attempt) must be at least 2 for us to see a delay.
goog.asserts.assert(this.maxAttempts_ >= 2,
'maxAttempts must be >= 2 for autoReset == true');
this.numAttempts_ = 1;
}
}

const currentAttempt = this.numAttempts_;
this.numAttempts_++;

if (currentAttempt == 0) {
goog.asserts.assert(!this.autoReset_, 'Failed to delay with auto-reset!');
return;
}

// We've already tried before, so delay the Promise.
/**
* @return {!Promise} Resolves when the caller may make an attempt, possibly
* after a delay. Rejects if no more attempts are allowed.
*/
async attempt() {
if (this.numAttempts_ >= this.maxAttempts_) {
if (this.autoReset_) {
this.reset_();
} else {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.PLAYER,
shaka.util.Error.Code.ATTEMPTS_EXHAUSTED);
}
}

// Fuzz the delay to avoid tons of clients hitting the server at once
// after it recovers from whatever is causing it to fail.
const fuzzedDelayMs = shaka.net.Backoff.fuzz_(
this.nextUnfuzzedDelay_, this.fuzzFactor_);
const currentAttempt = this.numAttempts_;
this.numAttempts_++;

await new Promise((resolve) => {
shaka.net.Backoff.defer(fuzzedDelayMs, resolve);
});
if (currentAttempt == 0) {
goog.asserts.assert(!this.autoReset_, 'Failed to delay with auto-reset!');
return;
}

// Update delay_ for next time.
this.nextUnfuzzedDelay_ *= this.backoffFactor_;
};
// We've already tried before, so delay the Promise.

// Fuzz the delay to avoid tons of clients hitting the server at once
// after it recovers from whatever is causing it to fail.
const fuzzedDelayMs = shaka.net.Backoff.fuzz_(
this.nextUnfuzzedDelay_, this.fuzzFactor_);

/**
* Gets a copy of the default retry parameters.
*
* @return {shaka.extern.RetryParameters}
*/
shaka.net.Backoff.defaultRetryParameters = function() {
// Use a function rather than a constant member so the calling code can
// modify the values without affecting other call results.
return {
maxAttempts: 2,
baseDelay: 1000,
backoffFactor: 2,
fuzzFactor: 0.5,
timeout: 0,
};
};
await new Promise((resolve) => {
shaka.net.Backoff.defer(fuzzedDelayMs, resolve);
});

// Update delay_ for next time.
this.nextUnfuzzedDelay_ *= this.backoffFactor_;
}

/**
* Fuzz the input value by +/- fuzzFactor. For example, a fuzzFactor of 0.5
* will create a random value that is between 50% and 150% of the input value.
*
* @param {number} value
* @param {number} fuzzFactor
* @return {number} The fuzzed value
* @private
*/
shaka.net.Backoff.fuzz_ = function(value, fuzzFactor) {
// A random number between -1 and +1.
const negToPosOne = (Math.random() * 2.0) - 1.0;

// A random number between -fuzzFactor and +fuzzFactor.
const negToPosFuzzFactor = negToPosOne * fuzzFactor;
/**
* Gets a copy of the default retry parameters.
*
* @return {shaka.extern.RetryParameters}
*/
static defaultRetryParameters() {
// Use a function rather than a constant member so the calling code can
// modify the values without affecting other call results.
return {
maxAttempts: 2,
baseDelay: 1000,
backoffFactor: 2,
fuzzFactor: 0.5,
timeout: 0,
};
}

// The original value, fuzzed by +/- fuzzFactor.
return value * (1.0 + negToPosFuzzFactor);
};
/**
* Fuzz the input value by +/- fuzzFactor. For example, a fuzzFactor of 0.5
* will create a random value that is between 50% and 150% of the input value.
*
* @param {number} value
* @param {number} fuzzFactor
* @return {number} The fuzzed value
* @private
*/
static fuzz_(value, fuzzFactor) {
// A random number between -1 and +1.
const negToPosOne = (Math.random() * 2.0) - 1.0;

// A random number between -fuzzFactor and +fuzzFactor.
const negToPosFuzzFactor = negToPosOne * fuzzFactor;

/**
* Reset state in autoReset mode.
* @private
*/
shaka.net.Backoff.prototype.reset_ = function() {
goog.asserts.assert(this.autoReset_, 'Should only be used for auto-reset!');
this.numAttempts_ = 1;
this.nextUnfuzzedDelay_ = this.baseDelay_;
};
// The original value, fuzzed by +/- fuzzFactor.
return value * (1.0 + negToPosFuzzFactor);
}

/**
* Reset state in autoReset mode.
* @private
*/
reset_() {
goog.asserts.assert(this.autoReset_, 'Should only be used for auto-reset!');
this.numAttempts_ = 1;
this.nextUnfuzzedDelay_ = this.baseDelay_;
}

/**
* This method is only public for testing. It allows us to intercept the
* time-delay call.
*
* @param {number} delayInMs
* @param {function()} callback
*/
shaka.net.Backoff.defer = function(delayInMs, callback) {
const timer = new shaka.util.Timer(callback);
timer.tickAfter(delayInMs / 1000);
/**
* This method is only public for testing. It allows us to intercept the
* time-delay call.
*
* @param {number} delayInMs
* @param {function()} callback
*/
static defer(delayInMs, callback) {
const timer = new shaka.util.Timer(callback);
timer.tickAfter(delayInMs / 1000);
}
};
Loading

0 comments on commit 74918b9

Please sign in to comment.