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