Skip to content

Commit 2744492

Browse files
committed
Use the same key for memcache and env['swift.infocache']
When we were caching directly to the WSGI environment, it made sense to have different keys for the different caches. Now that we have a separate data structure for the per-request cache, however, we ought to be consistent. Change-Id: I199cba6e5fc9ab4205bba369e6a2f34fc5ce22d4
1 parent 0fb92ce commit 2744492

File tree

13 files changed

+182
-201
lines changed

13 files changed

+182
-201
lines changed

swift/proxy/controllers/base.py

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -107,18 +107,6 @@ def delay_denial(func):
107107
return func
108108

109109

110-
def get_account_memcache_key(account):
111-
cache_key, env_key = _get_cache_key(account, None)
112-
return cache_key
113-
114-
115-
def get_container_memcache_key(account, container):
116-
if not container:
117-
raise ValueError("container not provided")
118-
cache_key, env_key = _get_cache_key(account, container)
119-
return cache_key
120-
121-
122110
def _prep_headers_to_info(headers, server_type):
123111
"""
124112
Helper method that iterates once over a dict of headers,
@@ -424,40 +412,32 @@ def get_account_info(env, app, swift_source=None):
424412
return info
425413

426414

427-
def _get_cache_key(account, container):
415+
def get_cache_key(account, container=None, obj=None):
428416
"""
429-
Get the keys for both memcache (cache_key) and env (env_key)
430-
where info about accounts and containers is cached
417+
Get the keys for both memcache and env['swift.infocache'] (cache_key)
418+
where info about accounts, containers, and objects is cached
431419
432420
:param account: The name of the account
433421
:param container: The name of the container (or None if account)
434-
:returns: a tuple of (cache_key, env_key)
422+
:param obj: The name of the object (or None if account or container)
423+
:returns: a string cache_key
435424
"""
436425

437-
if container:
426+
if obj:
427+
if not (account and container):
428+
raise ValueError('Object cache key requires account and container')
429+
cache_key = 'object/%s/%s/%s' % (account, container, obj)
430+
elif container:
431+
if not account:
432+
raise ValueError('Container cache key requires account')
438433
cache_key = 'container/%s/%s' % (account, container)
439434
else:
440435
cache_key = 'account/%s' % account
441436
# Use a unique environment cache key per account and one container.
442437
# This allows caching both account and container and ensures that when we
443438
# copy this env to form a new request, it won't accidentally reuse the
444439
# old container or account info
445-
env_key = 'swift.%s' % cache_key
446-
return cache_key, env_key
447-
448-
449-
def get_object_env_key(account, container, obj):
450-
"""
451-
Get the keys for env (env_key) where info about object is cached
452-
453-
:param account: The name of the account
454-
:param container: The name of the container
455-
:param obj: The name of the object
456-
:returns: a string env_key
457-
"""
458-
env_key = 'swift.object/%s/%s/%s' % (account,
459-
container, obj)
460-
return env_key
440+
return cache_key
461441

462442

463443
def set_info_cache(app, env, account, container, resp):
@@ -483,7 +463,7 @@ def set_info_cache(app, env, account, container, resp):
483463
cache_time = int(resp.headers.get(
484464
'X-Backend-Recheck-Account-Existence',
485465
DEFAULT_RECHECK_ACCOUNT_EXISTENCE))
486-
cache_key, env_key = _get_cache_key(account, container)
466+
cache_key = get_cache_key(account, container)
487467

488468
if resp:
489469
if resp.status_int in (HTTP_NOT_FOUND, HTTP_GONE):
@@ -494,7 +474,7 @@ def set_info_cache(app, env, account, container, resp):
494474
# Next actually set both memcache and the env cache
495475
memcache = getattr(app, 'memcache', None) or env.get('swift.cache')
496476
if not cache_time:
497-
infocache.pop(env_key, None)
477+
infocache.pop(cache_key, None)
498478
if memcache:
499479
memcache.delete(cache_key)
500480
return
@@ -505,7 +485,7 @@ def set_info_cache(app, env, account, container, resp):
505485
info = headers_to_account_info(resp.headers, resp.status_int)
506486
if memcache:
507487
memcache.set(cache_key, info, time=cache_time)
508-
infocache[env_key] = info
488+
infocache[cache_key] = info
509489
return info
510490

511491

@@ -525,14 +505,14 @@ def set_object_info_cache(app, env, account, container, obj, resp):
525505
:returns: the object info
526506
"""
527507

528-
env_key = get_object_env_key(account, container, obj)
508+
cache_key = get_cache_key(account, container, obj)
529509

530510
if 'swift.infocache' in env and not resp:
531-
env['swift.infocache'].pop(env_key, None)
511+
env['swift.infocache'].pop(cache_key, None)
532512
return
533513

534514
info = headers_to_object_info(resp.headers, resp.status_int)
535-
env.setdefault('swift.infocache', {})[env_key] = info
515+
env.setdefault('swift.infocache', {})[cache_key] = info
536516
return info
537517

538518

@@ -559,9 +539,9 @@ def _get_info_from_infocache(env, account, container=None):
559539
560540
:returns: a dictionary of cached info on cache hit, None on miss
561541
"""
562-
_junk, env_key = _get_cache_key(account, container)
563-
if 'swift.infocache' in env and env_key in env['swift.infocache']:
564-
return env['swift.infocache'][env_key]
542+
cache_key = get_cache_key(account, container)
543+
if 'swift.infocache' in env and cache_key in env['swift.infocache']:
544+
return env['swift.infocache'][cache_key]
565545
return None
566546

567547

@@ -577,7 +557,7 @@ def _get_info_from_memcache(app, env, account, container=None):
577557
:returns: a dictionary of cached info on cache hit, None on miss. Also
578558
returns None if memcache is not in use.
579559
"""
580-
cache_key, env_key = _get_cache_key(account, container)
560+
cache_key = get_cache_key(account, container)
581561
memcache = getattr(app, 'memcache', None) or env.get('swift.cache')
582562
if memcache:
583563
info = memcache.get(cache_key)
@@ -589,7 +569,7 @@ def _get_info_from_memcache(app, env, account, container=None):
589569
for subkey, value in info[key].items():
590570
if isinstance(value, six.text_type):
591571
info[key][subkey] = value.encode("utf-8")
592-
env.setdefault('swift.infocache', {})[env_key] = info
572+
env.setdefault('swift.infocache', {})[cache_key] = info
593573
return info
594574
return None
595575

@@ -680,8 +660,8 @@ def _get_object_info(app, env, account, container, obj, swift_source=None):
680660
:param obj: The unquoted name of the object
681661
:returns: the cached info or None if cannot be retrieved
682662
"""
683-
env_key = get_object_env_key(account, container, obj)
684-
info = env.get('swift.infocache', {}).get(env_key)
663+
cache_key = get_cache_key(account, container, obj)
664+
info = env.get('swift.infocache', {}).get(cache_key)
685665
if info:
686666
return info
687667
# Not in cache, let's try the object servers

test/unit/common/middleware/test_account_quotas.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@
1818

1919
from swift.common.middleware import account_quotas, copy
2020

21-
from swift.proxy.controllers.base import _get_cache_key, \
22-
headers_to_account_info, get_object_env_key, \
23-
headers_to_object_info
21+
from swift.proxy.controllers.base import get_cache_key, \
22+
headers_to_account_info, headers_to_object_info
2423

2524

2625
class FakeCache(object):
@@ -58,17 +57,17 @@ def __call__(self, env, start_response):
5857
return aresp(env, start_response)
5958
if env['REQUEST_METHOD'] == "HEAD" and \
6059
env['PATH_INFO'] == '/v1/a/c2/o2':
61-
env_key = get_object_env_key('a', 'c2', 'o2')
62-
env.setdefault('swift.infocache', {})[env_key] = \
60+
cache_key = get_cache_key('a', 'c2', 'o2')
61+
env.setdefault('swift.infocache', {})[cache_key] = \
6362
headers_to_object_info(self.headers, 200)
6463
start_response('200 OK', self.headers)
6564
elif env['REQUEST_METHOD'] == "HEAD" and \
6665
env['PATH_INFO'] == '/v1/a/c2/o3':
6766
start_response('404 Not Found', [])
6867
else:
6968
# Cache the account_info (same as a real application)
70-
cache_key, env_key = _get_cache_key('a', None)
71-
env.setdefault('swift.infocache', {})[env_key] = \
69+
cache_key = get_cache_key('a')
70+
env.setdefault('swift.infocache', {})[cache_key] = \
7271
headers_to_account_info(self.headers, 200)
7372
start_response('200 OK', self.headers)
7473
return []

test/unit/common/middleware/test_container_sync.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
from swift.common import swob
2525
from swift.common.middleware import container_sync
26-
from swift.proxy.controllers.base import _get_cache_key
26+
from swift.proxy.controllers.base import get_cache_key
2727
from swift.proxy.controllers.info import InfoController
2828

2929
from test.unit import FakeLogger
@@ -206,7 +206,7 @@ def test_invalid_sig(self):
206206
req = swob.Request.blank(
207207
'/v1/a/c', headers={'x-container-sync-auth': 'US nonce sig'})
208208
infocache = req.environ.setdefault('swift.infocache', {})
209-
infocache[_get_cache_key('a', 'c')[1]] = {'sync_key': 'abc'}
209+
infocache[get_cache_key('a', 'c')] = {'sync_key': 'abc'}
210210
resp = req.get_response(self.sync)
211211
self.assertEqual(resp.status, '401 Unauthorized')
212212
self.assertEqual(
@@ -226,7 +226,7 @@ def test_valid_sig(self):
226226
'x-container-sync-auth': 'US nonce ' + sig,
227227
'x-backend-inbound-x-timestamp': ts})
228228
infocache = req.environ.setdefault('swift.infocache', {})
229-
infocache[_get_cache_key('a', 'c')[1]] = {'sync_key': 'abc'}
229+
infocache[get_cache_key('a', 'c')] = {'sync_key': 'abc'}
230230
resp = req.get_response(self.sync)
231231
self.assertEqual(resp.status, '200 OK')
232232
self.assertEqual(resp.body, 'Response to Authorized Request')
@@ -241,7 +241,7 @@ def test_valid_sig2(self):
241241
req = swob.Request.blank(
242242
'/v1/a/c', headers={'x-container-sync-auth': 'US nonce ' + sig})
243243
infocache = req.environ.setdefault('swift.infocache', {})
244-
infocache[_get_cache_key('a', 'c')[1]] = {'sync_key': 'abc'}
244+
infocache[get_cache_key('a', 'c')] = {'sync_key': 'abc'}
245245
resp = req.get_response(self.sync)
246246
self.assertEqual(resp.status, '200 OK')
247247
self.assertEqual(resp.body, 'Response to Authorized Request')

0 commit comments

Comments
 (0)