cubicweb/pyramid/tools.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 20 Jan 2017 18:17:04 +0100
changeset 11919 3a6746dfc57f
parent 11827 851b6bd79b50
child 11958 950ce7d9f642
permissions -rw-r--r--
Change hooks control (deny_all_hooks_but / allow_all_hooks_but) to be more predictable Prior to this, if one execute code like: with cnx.hooks.deny_all_hooks_but('metadata'): with cnx.hooks.deny_all_hooks_but(): # mycode 'metadata' hooks will be activated anyway in the inner block, which is rather unexpected (of course in real life you only see the latest hooks control statement, the former being higher in the call stack). This is due to the underlying usage of old `enable_hook_categories` / `disable_hook_categories` methods, which were introduced much before the now official context manager based API (with `cnx.[deny|all]_all_hooks_but(...)`). To move on, this patch drop the two legacy methods, rename and privatize related internal state on the connection (`hooks_mode` becomes `_hooks_mode`, `disabled_hook_cats` and `enabled_hook_cats` become `_hooks_categories`) and reimplement the `_hooks_control` context manager to simply update them. See the added unit test for details.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11551
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
     1
"""Various tools.
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
     2
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
     3
.. warning::
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
     4
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
     5
    This module should be considered as internal implementation details. Use
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
     6
    with caution, as the API may change without notice.
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
     7
"""
11550
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     8
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     9
#: A short-term cache for user clones.
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    10
#: used by cached_build_user to speed-up repetitive calls to build_user
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    11
#: The expiration is handled in a dumb and brutal way: the whole cache is
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    12
#: cleared every 5 minutes.
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    13
_user_cache = {}
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    14
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    15
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    16
def clone_user(repo, user):
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    17
    """Clone a CWUser instance.
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    18
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    19
    .. warning::
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    20
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    21
        The returned clone is detached from any cnx.
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    22
        Before using it in any way, it should be attached to a cnx that has not
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    23
        this user already loaded.
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    24
    """
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    25
    CWUser = repo.vreg['etypes'].etype_class('CWUser')
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    26
    clone = CWUser(
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    27
        None,
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    28
        rset=user.cw_rset.copy(),
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    29
        row=user.cw_row,
11701
ca536eec556b [pyramid] Retrieve user's groups using a custom RQL instead of user's groups property
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11631
diff changeset
    30
        col=user.cw_col)
11550
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    31
    clone.cw_attr_cache = dict(user.cw_attr_cache)
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    32
    return clone
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    33
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    34
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    35
def cnx_attach_entity(cnx, entity):
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    36
    """Attach an entity to a cnx."""
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    37
    entity._cw = cnx
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    38
    if entity.cw_rset:
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    39
        entity.cw_rset.req = cnx
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    40
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    41
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    42
def cached_build_user(repo, eid):
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    43
    """Cached version of
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    44
    :meth:`cubicweb.server.repository.Repository._build_user`
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    45
    """
11827
851b6bd79b50 [pyramid] No more need for an internal connection when user is cached
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
    46
    if eid in _user_cache:
851b6bd79b50 [pyramid] No more need for an internal connection when user is cached
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
    47
        user, lang = _user_cache[eid]
851b6bd79b50 [pyramid] No more need for an internal connection when user is cached
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
    48
        entity = clone_user(repo, user)
851b6bd79b50 [pyramid] No more need for an internal connection when user is cached
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
    49
        return entity, lang
851b6bd79b50 [pyramid] No more need for an internal connection when user is cached
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
    50
11550
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    51
    with repo.internal_cnx() as cnx:
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    52
        user = repo._build_user(cnx, eid)
11824
d7ecf6dab085 Fix AttributeError for "lang" on repo/client connections
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
    53
        lang = user.prefered_language()
11550
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    54
        user.cw_clear_relation_cache()
11824
d7ecf6dab085 Fix AttributeError for "lang" on repo/client connections
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
    55
        _user_cache[eid] = (clone_user(repo, user), lang)
d7ecf6dab085 Fix AttributeError for "lang" on repo/client connections
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
    56
        return user, lang
11550
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    57
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    58
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    59
def clear_cache():
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    60
    """Clear the user cache"""
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    61
    _user_cache.clear()
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    62
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    63
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    64
def includeme(config):
11551
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    65
    """Start the cache maintenance loop task.
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    66
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11551
diff changeset
    67
    Automatically included by :func:`cubicweb.pyramid.make_cubicweb_application`.
11551
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    68
    """
11550
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    69
    repo = config.registry['cubicweb.repository']
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    70
    interval = int(config.registry.settings.get(
11811
f09efeead7f9 Fix broken flake8 configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11701
diff changeset
    71
        'cubicweb.usercache.expiration_time', 60 * 5))
11550
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    72
    repo.looping_task(interval, clear_cache)