Edgewall Software

Ticket #4245: perm-addcache.patch

File perm-addcache.patch, 4.2 KB (added by Chris Everest <ceverest@…>, 3 years ago)

Add caching logic to perms.py

  • trac/perm.py

    diff -rupN Trac-0.11.2.1-original/trac/perm.py Trac-0.11.2.1/trac/perm.py
    old new class DefaultPermissionStore(Component): 
    153153    permissions and groups. 
    154154    """ 
    155155    implements(IPermissionStore) 
     156 
     157    # Number of seconds that the cached permission table is valid for. 
     158    CACHE_EXPIRY = 5 
     159    # How frequently to clear the permission table cache 
     160    CACHE_REAP_TIME = 60 
     161 
     162    def __init__(self): 
     163        self.permission_table_cache = {} 
     164        self.last_reap = time() 
    156165 
    157166    group_providers = ExtensionPoint(IPermissionGroupProvider) 
    158167 
    class DefaultPermissionStore(Component): 
    165174        the action column: such a record represents a group and not an actual 
    166175        permission, and declares that the user is part of that group. 
    167176        """ 
    168         subjects = set([username]) 
     177       subjects = set([username]) 
    169178        for provider in self.group_providers:   
    170179            subjects.update(provider.get_permission_groups(username)) 
    171  
    172180        actions = set([]) 
    173         db = self.env.get_db_cnx() 
    174         cursor = db.cursor() 
    175         cursor.execute("SELECT username,action FROM permission") 
    176         rows = cursor.fetchall() 
     181 
     182       # Begin caching work 
     183       now = time() 
     184 
     185        if now - self.last_reap > self.CACHE_REAP_TIME: 
     186            self.permission_table_cache = {}    
     187            self.last_reap = time() 
     188 
     189        timestamp, rows = self.permission_table_cache.get('query', (0, None)) 
     190 
     191       # Cache Hit? 
     192       if now - timestamp > self.CACHE_EXPIRY:  
     193           # no, proceed to query the database  
     194            db = self.env.get_db_cnx() 
     195            cursor = db.cursor() 
     196            cursor.execute("SELECT username,action FROM permission") 
     197            rows = cursor.fetchall() 
     198            self.permission_table_cache['query'] = (now, rows) 
     199 
    177200        while True: 
    178201            num_users = len(subjects) 
    179202            num_actions = len(actions) 
    class DefaultPermissionPolicy(Component) 
    267290    # IPermissionPolicy methods 
    268291 
    269292    def check_permission(self, action, username, resource, perm): 
    270         now = time() 
     293        now = time() 
    271294 
    272295        if now - self.last_reap > self.CACHE_REAP_TIME: 
    273296            self.permission_cache = {} 
    class PermissionSystem(Component): 
    292315    implements(IPermissionRequestor) 
    293316 
    294317    requestors = ExtensionPoint(IPermissionRequestor) 
     318     
     319    # Number of seconds that cached userlist with a specific 
     320    # permission is valid for. 
     321    CACHE_EXPIRY = 5 
     322    # How frequently to clear the userlist w/permission cache 
     323    CACHE_REAP_TIME = 60    
     324 
     325    def __init__(self): 
     326        self.users_with_perm_cache = {} 
     327        self.last_reap = time() 
    295328 
    296329    store = ExtensionOption('trac', 'permission_store', IPermissionStore, 
    297330                            'DefaultPermissionStore', 
    class PermissionSystem(Component): 
    383416            for action in requestor.get_permission_actions(): 
    384417                for child in action[1]: 
    385418                    parent_map.setdefault(child, []).append(action[0]) 
    386  
    387         satisfying_perms = {} 
     419         
     420        satisfying_perms = {} 
    388421        def _append_with_parents(action): 
    389422            if action in satisfying_perms: 
    390423                return # avoid unneccesary work and infinite loops 
    class PermissionSystem(Component): 
    392425            if action in parent_map: 
    393426                map(_append_with_parents, parent_map[action]) 
    394427        _append_with_parents(permission) 
     428         
     429        # Begin caching work 
     430        now = time() 
     431 
     432        if now - self.last_reap > self.CACHE_REAP_TIME: 
     433            self.users_with_perm_cache = {} 
     434            self.last_reap = time() 
     435         
     436        timestamp, userlist = self.users_with_perm_cache.get(permission, (0, None)) 
     437         
     438        # Cache hit? 
     439        if now - timestamp > self.CACHE_EXPIRY: 
     440            # No, Pull userlist from database. 
     441            userlist = self.store.get_users_with_permissions(satisfying_perms.keys()) 
     442            self.users_with_perm_cache[permission] = (now, userlist) 
    395443 
    396         return self.store.get_users_with_permissions(satisfying_perms.keys()) 
     444        return userlist or None 
    397445 
    398446    def expand_actions(self, actions): 
    399447        """Helper method for expanding all meta actions."""