From 074d14cc6ca5e7064d97a29976c728a62b30eafb Mon Sep 17 00:00:00 2001 From: Evan Jones Date: Wed, 26 Oct 2016 14:24:52 -0400 Subject: [PATCH 1/2] storage_api: Avoid OverQuotaError from get_service_account_name Commit 10e7febf00 assigned app_identity.get_service_account_name to a local variable, outside of the if statement. This means it gets called every time this function is called, which makes an RPC on App Engine. During periods of high activity, this can exceed the per-minute API quota and raise OverQuotaError. To fix this, only call this if local_run() is True, which should only happen in development and never in App Engine production. --- python/src/cloudstorage/storage_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/src/cloudstorage/storage_api.py b/python/src/cloudstorage/storage_api.py index 26254fd..0a71d4d 100644 --- a/python/src/cloudstorage/storage_api.py +++ b/python/src/cloudstorage/storage_api.py @@ -66,9 +66,9 @@ def _get_storage_api(retry_params, account_id=None): # when running local unit tests, the service account is test@localhost # from google.appengine.api.app_identity.app_identity_stub.APP_SERVICE_ACCOUNT_NAME - service_account = app_identity.get_service_account_name() + # call get_service_account_name rarely: it can raise OverQuotaException if (common.local_run() and not common.get_access_token() - and (not service_account or service_account.endswith('@localhost'))): + and app_identity.get_service_account_name().endswith('@localhost')): api.api_url = common.local_api_url() if common.get_access_token(): api.token = common.get_access_token() From 933c9032d7423988c47352333bf92f36e75ab535 Mon Sep 17 00:00:00 2001 From: Evan Jones Date: Tue, 20 Mar 2018 15:37:27 -0400 Subject: [PATCH 2/2] fix for dev_appserver.py --- python/src/cloudstorage/storage_api.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/python/src/cloudstorage/storage_api.py b/python/src/cloudstorage/storage_api.py index 0a71d4d..b76a129 100644 --- a/python/src/cloudstorage/storage_api.py +++ b/python/src/cloudstorage/storage_api.py @@ -41,6 +41,11 @@ from google.appengine.api import app_identity +def _is_local_service_account(): + service_account_name = app_identity.get_service_account_name() + return service_account_name == '' or service_account_name.endswith('@localhost') + + def _get_storage_api(retry_params, account_id=None): """Returns storage_api instance for API methods. @@ -67,8 +72,7 @@ def _get_storage_api(retry_params, account_id=None): # when running local unit tests, the service account is test@localhost # from google.appengine.api.app_identity.app_identity_stub.APP_SERVICE_ACCOUNT_NAME # call get_service_account_name rarely: it can raise OverQuotaException - if (common.local_run() and not common.get_access_token() - and app_identity.get_service_account_name().endswith('@localhost')): + if (common.local_run() and not common.get_access_token() and _is_local_service_account()): api.api_url = common.local_api_url() if common.get_access_token(): api.token = common.get_access_token()