Merge "Stop memoizing on request arguments in nova api"
This commit is contained in:
@@ -104,3 +104,71 @@ def memoized(func):
|
||||
# it doesn't keep the instances in memory forever. We might want to separate
|
||||
# them in the future, however.
|
||||
memoized_method = memoized
|
||||
|
||||
|
||||
def memoized_with_request(request_func, request_index=0):
|
||||
"""Decorator for caching functions which receive a request argument
|
||||
|
||||
memoized functions with a request argument are memoized only during the
|
||||
rendering of a single view because the request argument is a new request
|
||||
instance on each view.
|
||||
|
||||
If you want a function to be memoized for multiple views use this
|
||||
decorator.
|
||||
|
||||
It replaces the request argument in the call to the decorated function
|
||||
with the result of calling request_func on that request object.
|
||||
|
||||
request_function is a function which will receive the request argument.
|
||||
|
||||
request_index indicates which argument of the decorated function is the
|
||||
request object to pass into request_func, which will also be replaced
|
||||
by the result of request_func being called.
|
||||
|
||||
your memoized function will instead receive request_func(request)
|
||||
passed as argument at the request_index.
|
||||
|
||||
The intent of that function is to extract the information needed from the
|
||||
request, and thus the memoizing will operate just on that part of the
|
||||
request that is relevant to the function being memoized.
|
||||
|
||||
short example:
|
||||
|
||||
@memoized
|
||||
def _get_api_client(username, token_id, project_id, auth_url)
|
||||
return api_client.Client(username, token_id, project_id, auth_url)
|
||||
|
||||
def get_api_client(request):
|
||||
return _api_client(request.user.username,
|
||||
request.user.token.id,
|
||||
request.user.tenant_id)
|
||||
|
||||
@memoized_with_request(get_api_client)
|
||||
def some_api_function(api_client, *args, **kwargs):
|
||||
# is like returning get_api_client(
|
||||
# request).some_method(*args, **kwargs)
|
||||
# but with memoization.
|
||||
return api_client.some_method(*args, **kwargs)
|
||||
|
||||
@memoized_with_request(get_api_client, 1)
|
||||
def some_other_funt(param, api_client, other_param):
|
||||
# The decorated function will be called this way:
|
||||
# some_other_funt(param, request, other_param)
|
||||
# but will be called behind the scenes this way:
|
||||
# some_other_funt(param, get_api_client(request), other_param)
|
||||
return api_client.some_method(param, other_param)
|
||||
|
||||
See openstack_dashboard.api.nova for a complete example.
|
||||
"""
|
||||
def wrapper(func):
|
||||
memoized_func = memoized(func)
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapped(*args, **kwargs):
|
||||
args = list(args)
|
||||
request = args.pop(request_index)
|
||||
args.insert(request_index, request_func(request))
|
||||
return memoized_func(*args, **kwargs)
|
||||
|
||||
return wrapped
|
||||
return wrapper
|
||||
|
||||
Reference in New Issue
Block a user