sqlcache: protect read query too
authorPierre-Yves David <pierre-yves.david@octobus.net>
Mon, 27 Aug 2018 11:40:32 +0200
changeset 4011 3cb41bf56f16
parent 4010 4c2fcd53c601
child 4012 dbeac677e99a
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
@@ -437,10 +437,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):
@@ -478,14 +485,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
@@ -177,11 +177,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):