Retry on 503 error when generating functions upload URL (#811)

This commit is contained in:
Lauren Long
2018-07-02 13:17:34 -07:00
committed by GitHub
parent b342ba7bf1
commit 6e14dffe37
4 changed files with 93 additions and 84 deletions

View File

@@ -194,13 +194,28 @@ var api = {
reqOptions.qs = options.qs;
reqOptions.headers = options.headers;
var requestFunction = function() {
return _request(reqOptions);
};
if (options.auth === true) {
return api.addRequestHeaders(reqOptions).then(function(reqOptionsWithToken) {
return _request(reqOptionsWithToken);
});
requestFunction = function() {
return api.addRequestHeaders(reqOptions).then(function(reqOptionsWithToken) {
return _request(reqOptionsWithToken);
});
};
}
return _request(reqOptions);
return requestFunction().catch(function(err) {
if (
options.retryCodes &&
_.includes(options.retryCodes, _.get(err, "context.response.statusCode"))
) {
return new Promise(function(resolve) {
setTimeout(resolve, 1000);
}).then(requestFunction);
}
return Promise.reject(err);
});
},
getProject: function(projectId) {
return api

View File

@@ -26,11 +26,13 @@ function _functionsOpLogReject(func, type, err) {
function _generateUploadUrl(projectId, location) {
var parent = "projects/" + projectId + "/locations/" + location;
var endpoint = "/" + API_VERSION + "/" + parent + "/functions:generateUploadUrl";
return api
.request("POST", endpoint, {
auth: true,
json: false,
origin: api.functionsOrigin,
retryCodes: [503],
})
.then(
function(result) {

View File

@@ -8,127 +8,116 @@ var _ = require("lodash");
var API_VERSION = "v1beta1";
function _retryOnServerError(requestFunction) {
return requestFunction().catch(function(err) {
if (_.includes([500, 503], _.get(err, "context.response.statusCode"))) {
return new Promise(function(resolve) {
setTimeout(resolve, 1000);
}).then(requestFunction);
}
return Promise.reject(err);
});
}
function _listConfigs(projectId) {
return _retryOnServerError(function() {
return api.request("GET", utils.endpoint([API_VERSION, "projects", projectId, "configs"]), {
return api
.request("GET", utils.endpoint([API_VERSION, "projects", projectId, "configs"]), {
auth: true,
origin: api.runtimeconfigOrigin,
retryCodes: [500, 503],
})
.then(function(resp) {
return Promise.resolve(resp.body.configs);
});
}).then(function(resp) {
return Promise.resolve(resp.body.configs);
});
}
function _createConfig(projectId, configId) {
var path = _.join(["projects", projectId, "configs"], "/");
var endpoint = utils.endpoint([API_VERSION, path]);
return _retryOnServerError(function() {
return api.request("POST", endpoint, {
return api
.request("POST", endpoint, {
auth: true,
origin: api.runtimeconfigOrigin,
data: {
name: path + "/" + configId,
},
retryCodes: [500, 503],
})
.catch(function(err) {
if (_.get(err, "context.response.statusCode") === 409) {
// Config has already been created as part of a parallel operation during firebase functions:config:set
return Promise.resolve();
}
return Promise.reject(err);
});
}).catch(function(err) {
if (_.get(err, "context.response.statusCode") === 409) {
// Config has already been created as part of a parallel operation during firebase functions:config:set
return Promise.resolve();
}
return Promise.reject(err);
});
}
function _deleteConfig(projectId, configId) {
return _retryOnServerError(function() {
return api.request(
"DELETE",
utils.endpoint([API_VERSION, "projects", projectId, "configs", configId]),
{
auth: true,
origin: api.runtimeconfigOrigin,
return api
.request("DELETE", utils.endpoint([API_VERSION, "projects", projectId, "configs", configId]), {
auth: true,
origin: api.runtimeconfigOrigin,
retryCodes: [500, 503],
})
.catch(function(err) {
if (_.get(err, "context.response.statusCode") === 404) {
logger.debug("Config already deleted.");
return Promise.resolve();
}
);
}).catch(function(err) {
if (_.get(err, "context.response.statusCode") === 404) {
logger.debug("Config already deleted.");
return Promise.resolve();
}
return Promise.reject(err);
});
return Promise.reject(err);
});
}
function _listVariables(configPath) {
return _retryOnServerError(function() {
return api.request("GET", utils.endpoint([API_VERSION, configPath, "variables"]), {
return api
.request("GET", utils.endpoint([API_VERSION, configPath, "variables"]), {
auth: true,
origin: api.runtimeconfigOrigin,
retryCodes: [500, 503],
})
.then(function(resp) {
return Promise.resolve(resp.body.variables);
});
}).then(function(resp) {
return Promise.resolve(resp.body.variables);
});
}
function _getVariable(varPath) {
return _retryOnServerError(function() {
return api.request("GET", utils.endpoint([API_VERSION, varPath]), {
return api
.request("GET", utils.endpoint([API_VERSION, varPath]), {
auth: true,
origin: api.runtimeconfigOrigin,
retryCodes: [500, 503],
})
.then(function(resp) {
return Promise.resolve(resp.body);
});
}).then(function(resp) {
return Promise.resolve(resp.body);
});
}
function _createVariable(projectId, configId, varId, value) {
var path = _.join(["projects", projectId, "configs", configId, "variables"], "/");
var endpoint = utils.endpoint([API_VERSION, path]);
return _retryOnServerError(function() {
return api.request("POST", endpoint, {
return api
.request("POST", endpoint, {
auth: true,
origin: api.runtimeconfigOrigin,
data: {
name: path + "/" + varId,
text: value,
},
retryCodes: [500, 503],
})
.catch(function(err) {
if (_.get(err, "context.response.statusCode") === 404) {
// parent config doesn't exist yet
return _createConfig(projectId, configId).then(function() {
return _createVariable(projectId, configId, varId, value);
});
}
return Promise.reject(err);
});
}).catch(function(err) {
if (_.get(err, "context.response.statusCode") === 404) {
// parent config doesn't exist yet
return _createConfig(projectId, configId).then(function() {
return _createVariable(projectId, configId, varId, value);
});
}
return Promise.reject(err);
});
}
function _updateVariable(projectId, configId, varId, value) {
var path = _.join(["projects", projectId, "configs", configId, "variables", varId], "/");
var endpoint = utils.endpoint([API_VERSION, path]);
return _retryOnServerError(function() {
return api.request("PUT", endpoint, {
auth: true,
origin: api.runtimeconfigOrigin,
data: {
name: path,
text: value,
},
});
return api.request("PUT", endpoint, {
auth: true,
origin: api.runtimeconfigOrigin,
data: {
name: path,
text: value,
},
retryCodes: [500, 503],
});
}
function _setVariable(projectId, configId, varId, value) {
var path = _.join(["projects", projectId, "configs", configId, "variables", varId], "/");
return _getVariable(path)
@@ -147,18 +136,19 @@ function _deleteVariable(projectId, configId, varId) {
var endpoint =
utils.endpoint([API_VERSION, "projects", projectId, "configs", configId, "variables", varId]) +
"?recursive=true";
return _retryOnServerError(function() {
return api.request("DELETE", endpoint, {
return api
.request("DELETE", endpoint, {
auth: true,
origin: api.runtimeconfigOrigin,
retryCodes: [500, 503],
})
.catch(function(err) {
if (_.get(err, "context.response.statusCode") === 404) {
logger.debug("Variable already deleted.");
return Promise.resolve();
}
return Promise.reject(err);
});
}).catch(function(err) {
if (_.get(err, "context.response.statusCode") === 404) {
logger.debug("Variable already deleted.");
return Promise.resolve();
}
return Promise.reject(err);
});
}
module.exports = {

View File

@@ -3,6 +3,7 @@
var chalk = require("chalk");
var exec = require("child_process").exec;
var execSync = require("child_process").execSync;
var expect = require("chai").expect;
var fs = require("fs-extra");
var tmp = require("tmp");
@@ -21,6 +22,7 @@ var preTest = function() {
fs.copySync(projectDir, tmpDir);
api.setRefreshToken(configstore.get("tokens").refresh_token);
api.setScopes(scopes.CLOUD_PLATFORM);
execSync(localFirebase + " functions:config:unset foo", { cwd: tmpDir });
console.log("Done pretest prep.");
};