From bceaaa572484e0b103ed51f8f0bdc646b56beb84 Mon Sep 17 00:00:00 2001 From: Jack Robison Date: Tue, 27 Feb 2018 17:20:33 -0500 Subject: [PATCH 1/2] delay re-running query after database locked error --- lbrynet/database/storage.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lbrynet/database/storage.py b/lbrynet/database/storage.py index b0f8e0fd0..db661c8a1 100644 --- a/lbrynet/database/storage.py +++ b/lbrynet/database/storage.py @@ -78,7 +78,8 @@ def rerun_if_locked(f): log.warning("database was locked. rerunning %s with args %s, kwargs %s", str(f), str(args), str(kwargs)) if rerun_count < max_attempts: - return task.deferLater(reactor, 0, inner_wrapper, rerun_count + 1, *args, **kwargs) + delay = 2**rerun_count + return task.deferLater(reactor, delay, inner_wrapper, rerun_count + 1, *args, **kwargs) raise err def inner_wrapper(rerun_count, *args, **kwargs): From 96d435cebd6a67990b8078ba2297331b0c00c739 Mon Sep 17 00:00:00 2001 From: Jack Robison Date: Tue, 27 Feb 2018 17:21:22 -0500 Subject: [PATCH 2/2] don't import reactor, set in SqliteConnection --- lbrynet/database/storage.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lbrynet/database/storage.py b/lbrynet/database/storage.py index db661c8a1..ed6b663a3 100644 --- a/lbrynet/database/storage.py +++ b/lbrynet/database/storage.py @@ -4,7 +4,7 @@ import time import sqlite3 import traceback from decimal import Decimal -from twisted.internet import defer, task, reactor, threads +from twisted.internet import defer, task, threads from twisted.enterprise import adbapi from lbryschema.claim import ClaimDict @@ -73,6 +73,8 @@ def rerun_if_locked(f): max_attempts = 3 def rerun(err, rerun_count, *args, **kwargs): + connection = args[0] + reactor = connection.reactor log.debug("Failed to execute (%s): %s", err, args) if err.check(sqlite3.OperationalError) and err.value.message == "database is locked": log.warning("database was locked. rerunning %s with args %s, kwargs %s", @@ -82,8 +84,14 @@ def rerun_if_locked(f): return task.deferLater(reactor, delay, inner_wrapper, rerun_count + 1, *args, **kwargs) raise err + def check_needed_rerun(result, rerun_count): + if rerun_count: + log.info("successfully reran database query") + return result + def inner_wrapper(rerun_count, *args, **kwargs): d = f(*args, **kwargs) + d.addCallback(check_needed_rerun, rerun_count) d.addErrback(rerun, rerun_count, *args, **kwargs) return d @@ -101,6 +109,10 @@ class SqliteConnection(adbapi.ConnectionPool): def runInteraction(self, interaction, *args, **kw): return adbapi.ConnectionPool.runInteraction(self, interaction, *args, **kw) + @classmethod + def set_reactor(cls, reactor): + cls.reactor = reactor + class SQLiteStorage(object): CREATE_TABLES_QUERY = """ @@ -165,11 +177,14 @@ class SQLiteStorage(object): ); """ - def __init__(self, db_dir): + def __init__(self, db_dir, reactor=None): + if not reactor: + from twisted.internet import reactor self.db_dir = db_dir self._db_path = os.path.join(db_dir, "lbrynet.sqlite") log.info("connecting to database: %s", self._db_path) self.db = SqliteConnection(self._db_path) + self.db.set_reactor(reactor) def setup(self): def _create_tables(transaction):