sqlcache: protect read query too stable
authorPierre-Yves David <pierre-yves.david@octobus.net>
Mon, 27 Aug 2018 11:40:32 +0200
branchstable
changeset 4024 210f8abdfcd7
parent 4023 f59b262400fb
child 4025 971d2e81b5b6
sqlcache: protect read query too Some error (like locked database) can even happens when doing readonly operation. So we protect them too. At that point, it seems that pysqlite3 is not the right tool for this job.
hgext3rd/evolve/obsdiscovery.py
hgext3rd/evolve/stablerangecache.py
--- a/hgext3rd/evolve/obsdiscovery.py	Mon Aug 27 11:33:09 2018 +0200
+++ b/hgext3rd/evolve/obsdiscovery.py	Mon Aug 27 11:40:32 2018 +0200
@@ -432,10 +432,17 @@
         value = self._data.get(rangeid)
         if value is None and self._con is not None:
             nrange = (rangeid[0], rangeid[1])
-            obshash = self._con.execute(_queryobshash, nrange).fetchone()
-            if obshash is not None:
-                value = obshash[0]
-            self._data[rangeid] = value
+            try:
+                obshash = self._con.execute(_queryobshash, nrange).fetchone()
+                if obshash is not None:
+                    value = obshash[0]
+                self._data[rangeid] = value
+            except sqlite3.OperationalError:
+                # something is wrong with the sqlite db
+                # Since this is a cache, we ignore it.
+                if '_con' in vars(self):
+                    del self._con
+                self._new.clear()
         return value
 
     def __setitem__(self, rangeid, obshash):
@@ -473,14 +480,19 @@
                 if con is not None:
                     # always reset for now, the code detecting affect is buggy
                     # so we need to reset more broadly than we would like.
-                    if repo.stablerange._con is None:
-                        con.execute(_reset)
-                        self._data.clear()
-                    else:
-                        ranges = repo.stablerange.contains(repo, affected)
-                        con.executemany(_delete, ranges)
-                        for r in ranges:
-                            self._data.pop(r, None)
+                    try:
+                        if repo.stablerange._con is None:
+                            con.execute(_reset)
+                            self._data.clear()
+                        else:
+                            ranges = repo.stablerange.contains(repo, affected)
+                            con.executemany(_delete, ranges)
+                            for r in ranges:
+                                self._data.pop(r, None)
+                    except sqlite3.OperationalError as exc:
+                        repo.ui.log('evoext-cache', 'error while updating obshashrange cache: %s' % exc)
+                        del self._updating
+                        return
 
                 # rewarm key revisions
                 #
--- a/hgext3rd/evolve/stablerangecache.py	Mon Aug 27 11:33:09 2018 +0200
+++ b/hgext3rd/evolve/stablerangecache.py	Mon Aug 27 11:40:32 2018 +0200
@@ -178,11 +178,19 @@
         cache = self._subrangescache
         if rangeid not in cache and rangeid[0] <= self._ondisktiprev and self._con is not None:
             value = None
-            result = self._con.execute(_queryrange, rangeid).fetchone()
-            if result is not None: # database know about this node (skip in the future?)
-                value = self._con.execute(_querysubranges, rangeid).fetchall()
-            # in memory caching of the value
-            cache[rangeid] = value
+            try:
+                result = self._con.execute(_queryrange, rangeid).fetchone()
+                if result is not None: # database know about this node (skip in the future?)
+                    value = self._con.execute(_querysubranges, rangeid).fetchall()
+                # in memory caching of the value
+                cache[rangeid] = value
+            except sqlite3.OperationalError:
+                # something is wrong with the sqlite db
+                # Since this is a cache, we ignore it.
+                if '_con' in vars(self):
+                    del self._con
+                self._unsavedsubranges.clear()
+
         return cache.get(rangeid)
 
     def _setsub(self, rangeid, value):