From bda988eec11e859ae991da5789775908d0406379 Mon Sep 17 00:00:00 2001 From: Samuel Padgett Date: Wed, 30 Aug 2017 20:03:01 -0400 Subject: [PATCH] Avoid multiple selfsubjectrulesreviews requests If a selfsubjectrulesreviews for a project is already in flight, don't request the rules a second time. --- dist/origin-web-common-services.js | 21 +++++++++++++++++---- dist/origin-web-common.js | 21 +++++++++++++++++---- dist/origin-web-common.min.js | 11 +++++++---- src/services/authorizationService.js | 21 +++++++++++++++++---- 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/dist/origin-web-common-services.js b/dist/origin-web-common-services.js index 77a7d11..6caeb3f 100644 --- a/dist/origin-web-common-services.js +++ b/dist/origin-web-common-services.js @@ -899,6 +899,10 @@ angular.module("openshiftCommonServices") }); }; + // Avoid loading rules twice if another request is already in flight. Key + // is the project name, value is the promise. + var inFlightRulesRequests = {}; + // forceRefresh is a boolean to bust the cache & request new perms var getProjectRules = function(projectName, forceRefresh) { var deferred = $q.defer(); @@ -908,11 +912,18 @@ angular.module("openshiftCommonServices") if (!projectRules || projectRules.forceRefresh || forceRefresh) { // Check if APIserver contains 'selfsubjectrulesreviews' resource. If not switch to permissive mode. if (APIService.apiInfo(rulesResource)) { + // If a request is already in flight, return the promise for that request. + if (inFlightRulesRequests[projectName]) { + return inFlightRulesRequests[projectName]; + } + Logger.log("AuthorizationService, loading user rules for " + projectName + " project"); - var object = {kind: "SelfSubjectRulesReview", - apiVersion: "v1" - }; - DataService.create(rulesResource, null, object, {namespace: projectName}).then( + inFlightRulesRequests[projectName] = deferred.promise; + var resourceGroupVersion = { + kind: "SelfSubjectRulesReview", + apiVersion: "v1" + }; + DataService.create(rulesResource, null, resourceGroupVersion, {namespace: projectName}).then( function(data) { var normalizedData = normalizeRules(data.status.rules); var canUserAddToProject = canAddToProjectCheck(data.status.rules); @@ -925,6 +936,8 @@ angular.module("openshiftCommonServices") }, function() { permissiveMode = true; deferred.resolve(); + }).finally(function() { + delete inFlightRulesRequests[projectName]; }); } else { Logger.log("AuthorizationService, resource 'selfsubjectrulesreviews' is not part of APIserver. Switching into permissive mode."); diff --git a/dist/origin-web-common.js b/dist/origin-web-common.js index 3f2a38f..be6cf13 100644 --- a/dist/origin-web-common.js +++ b/dist/origin-web-common.js @@ -2768,6 +2768,10 @@ angular.module("openshiftCommonServices") }); }; + // Avoid loading rules twice if another request is already in flight. Key + // is the project name, value is the promise. + var inFlightRulesRequests = {}; + // forceRefresh is a boolean to bust the cache & request new perms var getProjectRules = function(projectName, forceRefresh) { var deferred = $q.defer(); @@ -2777,11 +2781,18 @@ angular.module("openshiftCommonServices") if (!projectRules || projectRules.forceRefresh || forceRefresh) { // Check if APIserver contains 'selfsubjectrulesreviews' resource. If not switch to permissive mode. if (APIService.apiInfo(rulesResource)) { + // If a request is already in flight, return the promise for that request. + if (inFlightRulesRequests[projectName]) { + return inFlightRulesRequests[projectName]; + } + Logger.log("AuthorizationService, loading user rules for " + projectName + " project"); - var object = {kind: "SelfSubjectRulesReview", - apiVersion: "v1" - }; - DataService.create(rulesResource, null, object, {namespace: projectName}).then( + inFlightRulesRequests[projectName] = deferred.promise; + var resourceGroupVersion = { + kind: "SelfSubjectRulesReview", + apiVersion: "v1" + }; + DataService.create(rulesResource, null, resourceGroupVersion, {namespace: projectName}).then( function(data) { var normalizedData = normalizeRules(data.status.rules); var canUserAddToProject = canAddToProjectCheck(data.status.rules); @@ -2794,6 +2805,8 @@ angular.module("openshiftCommonServices") }, function() { permissiveMode = true; deferred.resolve(); + }).finally(function() { + delete inFlightRulesRequests[projectName]; }); } else { Logger.log("AuthorizationService, resource 'selfsubjectrulesreviews' is not part of APIserver. Switching into permissive mode."); diff --git a/dist/origin-web-common.min.js b/dist/origin-web-common.min.js index 518a475..b32d069 100644 --- a/dist/origin-web-common.min.js +++ b/dist/origin-web-common.min.js @@ -1080,17 +1080,18 @@ return _.some(rule.resources, function(resource) { return checkResource(resource) && !_.isEmpty(_.intersection(rule.verbs, [ "*", "create", "update" ])); }); }); -}, getProjectRules = function(projectName, forceRefresh) { +}, inFlightRulesRequests = {}, getProjectRules = function(projectName, forceRefresh) { var deferred = $q.defer(); currentProject = projectName; var projectRules = cachedRulesByProject.get(projectName), rulesResource = "selfsubjectrulesreviews"; if (!projectRules || projectRules.forceRefresh || forceRefresh) if (APIService.apiInfo(rulesResource)) { -Logger.log("AuthorizationService, loading user rules for " + projectName + " project"); -var object = { +if (inFlightRulesRequests[projectName]) return inFlightRulesRequests[projectName]; +Logger.log("AuthorizationService, loading user rules for " + projectName + " project"), inFlightRulesRequests[projectName] = deferred.promise; +var resourceGroupVersion = { kind:"SelfSubjectRulesReview", apiVersion:"v1" }; -DataService.create(rulesResource, null, object, { +DataService.create(rulesResource, null, resourceGroupVersion, { namespace:projectName }).then(function(data) { var normalizedData = normalizeRules(data.status.rules), canUserAddToProject = canAddToProjectCheck(data.status.rules); @@ -1102,6 +1103,8 @@ cacheTimestamp:_.now() }), deferred.resolve(); }, function() { permissiveMode = !0, deferred.resolve(); +})["finally"](function() { +delete inFlightRulesRequests[projectName]; }); } else Logger.log("AuthorizationService, resource 'selfsubjectrulesreviews' is not part of APIserver. Switching into permissive mode."), permissiveMode = !0, deferred.resolve(); else Logger.log("AuthorizationService, using cached rules for " + projectName + " project"), _.now() - projectRules.cacheTimestamp >= 6e5 && (projectRules.forceRefresh = !0), deferred.resolve(); return deferred.promise; diff --git a/src/services/authorizationService.js b/src/services/authorizationService.js index 2ece23f..e888a98 100644 --- a/src/services/authorizationService.js +++ b/src/services/authorizationService.js @@ -52,6 +52,10 @@ angular.module("openshiftCommonServices") }); }; + // Avoid loading rules twice if another request is already in flight. Key + // is the project name, value is the promise. + var inFlightRulesRequests = {}; + // forceRefresh is a boolean to bust the cache & request new perms var getProjectRules = function(projectName, forceRefresh) { var deferred = $q.defer(); @@ -61,11 +65,18 @@ angular.module("openshiftCommonServices") if (!projectRules || projectRules.forceRefresh || forceRefresh) { // Check if APIserver contains 'selfsubjectrulesreviews' resource. If not switch to permissive mode. if (APIService.apiInfo(rulesResource)) { + // If a request is already in flight, return the promise for that request. + if (inFlightRulesRequests[projectName]) { + return inFlightRulesRequests[projectName]; + } + Logger.log("AuthorizationService, loading user rules for " + projectName + " project"); - var object = {kind: "SelfSubjectRulesReview", - apiVersion: "v1" - }; - DataService.create(rulesResource, null, object, {namespace: projectName}).then( + inFlightRulesRequests[projectName] = deferred.promise; + var resourceGroupVersion = { + kind: "SelfSubjectRulesReview", + apiVersion: "v1" + }; + DataService.create(rulesResource, null, resourceGroupVersion, {namespace: projectName}).then( function(data) { var normalizedData = normalizeRules(data.status.rules); var canUserAddToProject = canAddToProjectCheck(data.status.rules); @@ -78,6 +89,8 @@ angular.module("openshiftCommonServices") }, function() { permissiveMode = true; deferred.resolve(); + }).finally(function() { + delete inFlightRulesRequests[projectName]; }); } else { Logger.log("AuthorizationService, resource 'selfsubjectrulesreviews' is not part of APIserver. Switching into permissive mode.");