1 """
2 Accessor functions for the various immutables we have.
3
4 The main purpose of this module is to keep caches of resource descriptors,
5 and other items the parsing of which may take some time.
6
7 All you need to do is provide a function taking a "key" (a string, most
8 likely) and returning the object. Then call
9
10 base.caches.makeCache(<accessorName>, <function>)
11
12 After that, clients can call
13
14 base.caches.<accessorName>(key)
15
16 You can additionally provide an isDirty(res) function when calling makeCache.
17 This can return True if the resource is out of date and should be reloaded.
18
19 An alternative interface to registering caches is the registerCache function
20 (see there).
21 """
22
23
24
25
26
27
28
30 """is a registry for caches kept to be able to clear them.
31
32 A cache is assumed to be a dicitonary here.
33 """
36
41
46
49
50
51 _cacheRegistry = CacheRegistry()
52 clearCaches = _cacheRegistry.clearall
53 clearForName = _cacheRegistry.clearForName
54
55
57 """returns a callable that memoizes the results of creator.
58
59 The creator has to be a function taking an id and returning the
60 designated object.
61
62 The whole thing is thread-safe only when the creators are. It is
63 possible that arbitrarily many creators for the same id run. Only one
64 will win in the end.
65
66 Race conditions are possible when exceptions occur, but then creators
67 behaviour should only depend on id, and so it shouldn't matter.
68
69 isDirty can be a function returning true when the cache should be
70 cleared. The function is passed the current resource. If isDirty
71 is None, no such check is performed.
72 """
73 cache = {}
74 _cacheRegistry.register(cache)
75
76 def func(id):
77 if isDirty is not None and id in cache and isDirty(cache[id]):
78 clearForName(id)
79
80 if not id in cache:
81 try:
82 cache[id] = creator(id)
83 except Exception as exc:
84 cache[id] = exc
85 raise
86 if isinstance(cache[id], Exception):
87 raise cache[id]
88 else:
89 return cache[id]
90
91 return func
92
93
95 """registers a custom cache.
96
97 This function makes creationFunction available as base.caches.name,
98 and it registers cacheDict with the cache manager such that cacheDict
99 is cleared as necessary.
100
101 creationFunction must manage cacheDict itself, and of course it
102 must always use the instance passed to registerCache.
103
104 This is for "magic" things like getRD that has to deal with aliases
105 and such. For normal use, use makeCache.
106 """
107 globals()[name] = creationFunction
108 _cacheRegistry.register(cacheDict)
109
110
112 """creates a new function name to cache results to calls to callable.
113
114 isDirty can be a function returning true when the cache should be
115 cleared. The function is passed the current resource.
116 """
117 globals()[name] = _makeCache(callable, isDirty)
118