Edgewall Software

Ticket #6436: cache-get_ticket_fields-r6843.diff

File cache-get_ticket_fields-r6843.diff, 4.9 KB (added by cboos, 7 months ago)

cache for field data, using locking + cache reset method called when appropriate

  • trac/ticket/api.py

     
    1616 
    1717import re 
    1818from datetime import datetime 
     19try: 
     20    import threading 
     21except ImportError: 
     22    import dummy_threading as threading 
    1923 
    2024from genshi.builder import tag 
    2125 
     
    152156    def __init__(self): 
    153157        self.log.debug('action controllers for ticket workflow: %r' %  
    154158                [c.__class__.__name__ for c in self.action_controllers]) 
     159        self._fields_lock = threading.RLock() 
    155160 
    156161    # Public API 
    157162 
     
    180185 
    181186    def get_ticket_fields(self): 
    182187        """Returns the list of fields available for tickets.""" 
     188        # This is now cached - as it makes quite a number of things faster, 
     189        # e.g. #6436 
     190        if self._fields is None: 
     191            self._fields_lock.acquire() 
     192            try: 
     193                self._fields = self._get_ticket_fields() 
     194            finally: 
     195                self._fields_lock.release() 
     196        return [f.copy() for f in self._fields] 
     197 
     198    def reset_ticket_fields(self): 
     199        self._fields_lock.acquire() 
     200        try: 
     201            self._fields = None 
     202            self.config.touch() # brute force approach for now 
     203        finally: 
     204            self._fields_lock.release() 
     205 
     206    _fields = None 
     207    def _get_ticket_fields(self): 
    183208        from trac.ticket import model 
    184209 
    185210        db = self.env.get_db_cnx() 
     
    251276        return fields 
    252277 
    253278    def get_custom_fields(self): 
     279        if self._custom_fields is None: 
     280            self._fields_lock.acquire() 
     281            try: 
     282                self._custom_fields = self._get_custom_fields() 
     283            finally: 
     284                self._fields_lock.release() 
     285        return [f.copy() for f in self._custom_fields] 
     286 
     287    _custom_fields = None 
     288    def _get_custom_fields(self): 
    254289        fields = [] 
    255290        config = self.config['ticket-custom'] 
    256291        for name in [option for option, value in config.options() 
  • trac/ticket/model.py

     
    393393            db.commit() 
    394394        self.value = self._old_value = None 
    395395        self.name = self._old_name = None 
     396        TicketSystem(self.env).reset_ticket_fields() 
    396397 
    397398    def insert(self, db=None): 
    398399        assert not self.exists, 'Cannot insert existing %s' % self.type 
     
    418419            db.commit() 
    419420        self._old_name = self.name 
    420421        self._old_value = self.value 
     422        TicketSystem(self.env).reset_ticket_fields() 
    421423 
    422424    def update(self, db=None): 
    423425        assert self.exists, 'Cannot update non-existent %s' % self.type 
     
    444446            db.commit() 
    445447        self._old_name = self.name 
    446448        self._old_value = self.value 
     449        TicketSystem(self.env).reset_ticket_fields() 
    447450 
    448451    def select(cls, env, db=None): 
    449452        if not db: 
     
    530533 
    531534        if handle_ta: 
    532535            db.commit() 
     536        TicketSystem(self.env).reset_ticket_fields() 
    533537 
    534538    def insert(self, db=None): 
    535539        assert not self.exists, 'Cannot insert existing component' 
     
    549553 
    550554        if handle_ta: 
    551555            db.commit() 
     556        TicketSystem(self.env).reset_ticket_fields() 
    552557 
    553558    def update(self, db=None): 
    554559        assert self.exists, 'Cannot update non-existent component' 
     
    574579 
    575580        if handle_ta: 
    576581            db.commit() 
     582        TicketSystem(self.env).reset_ticket_fields() 
    577583 
    578584    def select(cls, env, db=None): 
    579585        if not db: 
     
    654660 
    655661        if handle_ta: 
    656662            db.commit() 
     663        TicketSystem(self.env).reset_ticket_fields() 
    657664 
    658665    def insert(self, db=None): 
    659666        assert self.name, 'Cannot create milestone with no name' 
     
    673680 
    674681        if handle_ta: 
    675682            db.commit() 
     683        TicketSystem(self.env).reset_ticket_fields() 
    676684 
    677685    def update(self, db=None): 
    678686        assert self.name, 'Cannot update milestone with no name' 
     
    698706 
    699707        if handle_ta: 
    700708            db.commit() 
     709        TicketSystem(self.env).reset_ticket_fields() 
    701710 
    702711    def select(cls, env, include_completed=True, db=None): 
    703712        if not db: 
     
    760769 
    761770        if handle_ta: 
    762771            db.commit() 
     772        TicketSystem(self.env).reset_ticket_fields() 
    763773 
    764774    def insert(self, db=None): 
    765775        assert not self.exists, 'Cannot insert existing version' 
     
    779789 
    780790        if handle_ta: 
    781791            db.commit() 
     792        TicketSystem(self.env).reset_ticket_fields() 
    782793 
    783794    def update(self, db=None): 
    784795        assert self.exists, 'Cannot update non-existent version' 
     
    804815 
    805816        if handle_ta: 
    806817            db.commit() 
     818        TicketSystem(self.env).reset_ticket_fields() 
    807819 
    808820    def select(cls, env, db=None): 
    809821        if not db: