|
1 """Various tools""" |
|
2 |
|
3 #: A short-term cache for user clones. |
|
4 #: used by cached_build_user to speed-up repetitive calls to build_user |
|
5 #: The expiration is handled in a dumb and brutal way: the whole cache is |
|
6 #: cleared every 5 minutes. |
|
7 _user_cache = {} |
|
8 |
|
9 |
|
10 def clone_user(repo, user): |
|
11 """Clone a CWUser instance. |
|
12 |
|
13 .. warning:: |
|
14 |
|
15 The returned clone is detached from any cnx. |
|
16 Before using it in any way, it should be attached to a cnx that has not |
|
17 this user already loaded. |
|
18 """ |
|
19 CWUser = repo.vreg['etypes'].etype_class('CWUser') |
|
20 clone = CWUser( |
|
21 None, |
|
22 rset=user.cw_rset.copy(), |
|
23 row=user.cw_row, |
|
24 col=user.cw_col, |
|
25 groups=set(user._groups) if hasattr(user, '_groups') else None, |
|
26 properties=dict(user._properties) |
|
27 if hasattr(user, '_properties') else None) |
|
28 clone.cw_attr_cache = dict(user.cw_attr_cache) |
|
29 return clone |
|
30 |
|
31 |
|
32 def cnx_attach_entity(cnx, entity): |
|
33 """Attach an entity to a cnx.""" |
|
34 entity._cw = cnx |
|
35 if entity.cw_rset: |
|
36 entity.cw_rset.req = cnx |
|
37 |
|
38 |
|
39 def cached_build_user(repo, eid): |
|
40 """Cached version of |
|
41 :meth:`cubicweb.server.repository.Repository._build_user` |
|
42 """ |
|
43 with repo.internal_cnx() as cnx: |
|
44 if eid in _user_cache: |
|
45 entity = clone_user(repo, _user_cache[eid]) |
|
46 cnx_attach_entity(cnx, entity) |
|
47 return entity |
|
48 |
|
49 user = repo._build_user(cnx, eid) |
|
50 user.cw_clear_relation_cache() |
|
51 _user_cache[eid] = clone_user(repo, user) |
|
52 return user |
|
53 |
|
54 |
|
55 def clear_cache(): |
|
56 """Clear the user cache""" |
|
57 _user_cache.clear() |
|
58 |
|
59 |
|
60 def includeme(config): |
|
61 repo = config.registry['cubicweb.repository'] |
|
62 interval = int(config.registry.settings.get( |
|
63 'cubicweb.usercache.expiration_time', 60*5)) |
|
64 repo.looping_task(interval, clear_cache) |