Changeset - d5707598fd64
[Not reviewed]
stable
0 1 0
Mads Kiilerich - 10 years ago 2016-01-05 16:23:22
madski@unity3d.com
db: fix unknown exception type in commit error handling

efce61aac33d was a blind fix. It failed because `from sqlalchemy import *`
doesn't import exc and the new except clause would thus fail. It also failed
because the session has to be rolled back after a commit failure.

Now, rework it to fix these issues.

Note that we are able to detect whether the commit failed for valid reasons ...
but we can't use that information to much ...
1 file changed with 10 insertions and 6 deletions:
0 comments (0 inline, 0 general)
kallithea/model/db.py
Show inline comments
 
@@ -31,12 +31,13 @@ import logging
 
import datetime
 
import traceback
 
import hashlib
 
import collections
 
import functools
 

	
 
import sqlalchemy
 
from sqlalchemy import *
 
from sqlalchemy.ext.hybrid import hybrid_property
 
from sqlalchemy.orm import relationship, joinedload, class_mapper, validates
 
from beaker.cache import cache_region, region_invalidate
 
from webob.exc import HTTPNotFound
 

	
 
@@ -2133,25 +2134,28 @@ class CacheInvalidation(Base, BaseModel)
 
        cache_key = cls._get_cache_key(key)
 

	
 
        if valid_cache_keys and cache_key in valid_cache_keys:
 
            return True
 

	
 
        inv_obj = cls.query().filter(cls.cache_key == cache_key).scalar()
 
        if not inv_obj:
 
        if inv_obj is None:
 
            inv_obj = CacheInvalidation(cache_key, repo_name)
 
        if inv_obj.cache_active:
 
        elif inv_obj.cache_active:
 
            return True
 
        inv_obj.cache_active = True
 
        Session().add(inv_obj)
 
        try:
 
            Session().commit()
 
        except exc.IntegrityError:
 
        except sqlalchemy.exc.IntegrityError:
 
            log.error('commit of CacheInvalidation failed - retrying')
 
            Session().rollback()
 
            inv_obj = cls.query().filter(cls.cache_key == cache_key).scalar()
 
            if not inv_obj:
 
                raise
 
            # TOCTOU - another thread added the key at the same time; no further action required
 
            if inv_obj is None:
 
                log.error('failed to create CacheInvalidation entry')
 
                # TODO: fail badly?
 
            # else: TOCTOU - another thread added the key at the same time; no further action required
 
        return False
 

	
 
    @classmethod
 
    def get_valid_cache_keys(cls):
 
        """
 
        Return opaque object with information of which caches still are valid
0 comments (0 inline, 0 general)