##// END OF EJS Templates
logging: use just func names for logs instead of objects with memory address (doesn't give any valueable info)
marcink -
r778:eaf5cd79 default
parent child
Show More
@@ -1,153 +1,153
1 # RhodeCode VCSServer provides access to different vcs backends via network.
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2019 RhodeCode GmbH
2 # Copyright (C) 2014-2019 RhodeCode GmbH
3 #
3 #
4 # This program is free software; you can redistribute it and/or modify
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
7 # (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
18 import os
18 import os
19 import logging
19 import logging
20 import functools
20 import functools
21 from decorator import decorate
21 from decorator import decorate
22
22
23 from dogpile.cache import CacheRegion
23 from dogpile.cache import CacheRegion
24 from dogpile.cache.util import compat
24 from dogpile.cache.util import compat
25
25
26 from vcsserver.utils import safe_str, sha1
26 from vcsserver.utils import safe_str, sha1
27
27
28
28
29 log = logging.getLogger(__name__)
29 log = logging.getLogger(__name__)
30
30
31
31
32 class RhodeCodeCacheRegion(CacheRegion):
32 class RhodeCodeCacheRegion(CacheRegion):
33
33
34 def conditional_cache_on_arguments(
34 def conditional_cache_on_arguments(
35 self, namespace=None,
35 self, namespace=None,
36 expiration_time=None,
36 expiration_time=None,
37 should_cache_fn=None,
37 should_cache_fn=None,
38 to_str=compat.string_type,
38 to_str=compat.string_type,
39 function_key_generator=None,
39 function_key_generator=None,
40 condition=True):
40 condition=True):
41 """
41 """
42 Custom conditional decorator, that will not touch any dogpile internals if
42 Custom conditional decorator, that will not touch any dogpile internals if
43 condition isn't meet. This works a bit different than should_cache_fn
43 condition isn't meet. This works a bit different than should_cache_fn
44 And it's faster in cases we don't ever want to compute cached values
44 And it's faster in cases we don't ever want to compute cached values
45 """
45 """
46 expiration_time_is_callable = compat.callable(expiration_time)
46 expiration_time_is_callable = compat.callable(expiration_time)
47
47
48 if function_key_generator is None:
48 if function_key_generator is None:
49 function_key_generator = self.function_key_generator
49 function_key_generator = self.function_key_generator
50
50
51 def get_or_create_for_user_func(key_generator, user_func, *arg, **kw):
51 def get_or_create_for_user_func(key_generator, user_func, *arg, **kw):
52
52
53 if not condition:
53 if not condition:
54 log.debug('Calling un-cached func:%s', user_func)
54 log.debug('Calling un-cached func:%s', user_func.func_name)
55 return user_func(*arg, **kw)
55 return user_func(*arg, **kw)
56
56
57 key = key_generator(*arg, **kw)
57 key = key_generator(*arg, **kw)
58
58
59 timeout = expiration_time() if expiration_time_is_callable \
59 timeout = expiration_time() if expiration_time_is_callable \
60 else expiration_time
60 else expiration_time
61
61
62 log.debug('Calling cached fn:%s', user_func)
62 log.debug('Calling cached fn:%s', user_func.func_name)
63 return self.get_or_create(key, user_func, timeout, should_cache_fn, (arg, kw))
63 return self.get_or_create(key, user_func, timeout, should_cache_fn, (arg, kw))
64
64
65 def cache_decorator(user_func):
65 def cache_decorator(user_func):
66 if to_str is compat.string_type:
66 if to_str is compat.string_type:
67 # backwards compatible
67 # backwards compatible
68 key_generator = function_key_generator(namespace, user_func)
68 key_generator = function_key_generator(namespace, user_func)
69 else:
69 else:
70 key_generator = function_key_generator(namespace, user_func, to_str=to_str)
70 key_generator = function_key_generator(namespace, user_func, to_str=to_str)
71
71
72 def refresh(*arg, **kw):
72 def refresh(*arg, **kw):
73 """
73 """
74 Like invalidate, but regenerates the value instead
74 Like invalidate, but regenerates the value instead
75 """
75 """
76 key = key_generator(*arg, **kw)
76 key = key_generator(*arg, **kw)
77 value = user_func(*arg, **kw)
77 value = user_func(*arg, **kw)
78 self.set(key, value)
78 self.set(key, value)
79 return value
79 return value
80
80
81 def invalidate(*arg, **kw):
81 def invalidate(*arg, **kw):
82 key = key_generator(*arg, **kw)
82 key = key_generator(*arg, **kw)
83 self.delete(key)
83 self.delete(key)
84
84
85 def set_(value, *arg, **kw):
85 def set_(value, *arg, **kw):
86 key = key_generator(*arg, **kw)
86 key = key_generator(*arg, **kw)
87 self.set(key, value)
87 self.set(key, value)
88
88
89 def get(*arg, **kw):
89 def get(*arg, **kw):
90 key = key_generator(*arg, **kw)
90 key = key_generator(*arg, **kw)
91 return self.get(key)
91 return self.get(key)
92
92
93 user_func.set = set_
93 user_func.set = set_
94 user_func.invalidate = invalidate
94 user_func.invalidate = invalidate
95 user_func.get = get
95 user_func.get = get
96 user_func.refresh = refresh
96 user_func.refresh = refresh
97 user_func.key_generator = key_generator
97 user_func.key_generator = key_generator
98 user_func.original = user_func
98 user_func.original = user_func
99
99
100 # Use `decorate` to preserve the signature of :param:`user_func`.
100 # Use `decorate` to preserve the signature of :param:`user_func`.
101
101
102 return decorate(user_func, functools.partial(
102 return decorate(user_func, functools.partial(
103 get_or_create_for_user_func, key_generator))
103 get_or_create_for_user_func, key_generator))
104
104
105 return cache_decorator
105 return cache_decorator
106
106
107
107
108 def make_region(*arg, **kw):
108 def make_region(*arg, **kw):
109 return RhodeCodeCacheRegion(*arg, **kw)
109 return RhodeCodeCacheRegion(*arg, **kw)
110
110
111
111
112 def get_default_cache_settings(settings, prefixes=None):
112 def get_default_cache_settings(settings, prefixes=None):
113 prefixes = prefixes or []
113 prefixes = prefixes or []
114 cache_settings = {}
114 cache_settings = {}
115 for key in settings.keys():
115 for key in settings.keys():
116 for prefix in prefixes:
116 for prefix in prefixes:
117 if key.startswith(prefix):
117 if key.startswith(prefix):
118 name = key.split(prefix)[1].strip()
118 name = key.split(prefix)[1].strip()
119 val = settings[key]
119 val = settings[key]
120 if isinstance(val, compat.string_types):
120 if isinstance(val, compat.string_types):
121 val = val.strip()
121 val = val.strip()
122 cache_settings[name] = val
122 cache_settings[name] = val
123 return cache_settings
123 return cache_settings
124
124
125
125
126 def compute_key_from_params(*args):
126 def compute_key_from_params(*args):
127 """
127 """
128 Helper to compute key from given params to be used in cache manager
128 Helper to compute key from given params to be used in cache manager
129 """
129 """
130 return sha1("_".join(map(safe_str, args)))
130 return sha1("_".join(map(safe_str, args)))
131
131
132
132
133 def backend_key_generator(backend):
133 def backend_key_generator(backend):
134 """
134 """
135 Special wrapper that also sends over the backend to the key generator
135 Special wrapper that also sends over the backend to the key generator
136 """
136 """
137 def wrapper(namespace, fn):
137 def wrapper(namespace, fn):
138 return key_generator(backend, namespace, fn)
138 return key_generator(backend, namespace, fn)
139 return wrapper
139 return wrapper
140
140
141
141
142 def key_generator(backend, namespace, fn):
142 def key_generator(backend, namespace, fn):
143 fname = fn.__name__
143 fname = fn.__name__
144
144
145 def generate_key(*args):
145 def generate_key(*args):
146 backend_prefix = getattr(backend, 'key_prefix', None) or 'backend_prefix'
146 backend_prefix = getattr(backend, 'key_prefix', None) or 'backend_prefix'
147 namespace_pref = namespace or 'default_namespace'
147 namespace_pref = namespace or 'default_namespace'
148 arg_key = compute_key_from_params(*args)
148 arg_key = compute_key_from_params(*args)
149 final_key = "{}:{}:{}_{}".format(backend_prefix, namespace_pref, fname, arg_key)
149 final_key = "{}:{}:{}_{}".format(backend_prefix, namespace_pref, fname, arg_key)
150
150
151 return final_key
151 return final_key
152
152
153 return generate_key
153 return generate_key
General Comments 0
You need to be logged in to leave comments. Login now