pyramid_cubicweb/tools.py
author David Douard <david.douard@logilab.fr>
Tue, 22 Mar 2016 14:01:44 +0100
changeset 11611 9d2bb6bdb5c8
parent 11551 444cd2bba89d
permissions -rw-r--r--
[tests] add a __main__ handler the relative import in test_rest_api.py needs to be modified to prevent a ValueError: Attempted relative import in non-package
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,
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    30
        col=user.cw_col,
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    31
        groups=set(user._groups) if hasattr(user, '_groups') else None,
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    32
        properties=dict(user._properties)
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    33
        if hasattr(user, '_properties') else None)
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    34
    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
    35
    return clone
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    36
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    37
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    38
def cnx_attach_entity(cnx, entity):
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    39
    """Attach an entity to a cnx."""
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    40
    entity._cw = cnx
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    41
    if entity.cw_rset:
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    42
        entity.cw_rset.req = cnx
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    43
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    44
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    45
def cached_build_user(repo, eid):
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    46
    """Cached version of
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    47
    :meth:`cubicweb.server.repository.Repository._build_user`
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    48
    """
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    49
    with repo.internal_cnx() as cnx:
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    50
        if eid in _user_cache:
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    51
            entity = clone_user(repo, _user_cache[eid])
11551
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    52
            # XXX the cnx is needed here so that the CWUser instance has an
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    53
            # access to the vreg, which it needs when its 'prefered_language'
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    54
            # property is accessed.
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    55
            # If this property did not need a cnx to access a vreg, we could
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    56
            # avoid the internal_cnx() and save more time.
11550
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    57
            cnx_attach_entity(cnx, entity)
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    58
            return entity
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    59
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    60
        user = repo._build_user(cnx, eid)
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    61
        user.cw_clear_relation_cache()
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    62
        _user_cache[eid] = clone_user(repo, user)
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    63
        return user
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    64
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    65
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    66
def clear_cache():
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    67
    """Clear the user cache"""
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    68
    _user_cache.clear()
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    69
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    70
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    71
def includeme(config):
11551
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    72
    """Start the cache maintenance loop task.
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    73
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    74
    Automatically included by :func:`pyramid_cubicweb.make_cubicweb_application`.
444cd2bba89d [doc] Document tools
Christophe de Vienne <christophe@unlish.com>
parents: 11550
diff changeset
    75
    """
11550
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    76
    repo = config.registry['cubicweb.repository']
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    77
    interval = int(config.registry.settings.get(
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    78
        'cubicweb.usercache.expiration_time', 60*5))
38ed4c3ac3de [tools] Provide a faster build_user
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    79
    repo.looping_task(interval, clear_cache)