forked from lix-project/lix
Warn after a second of being busy instead of immediately.
Getting the occasional SQLITE_BUSY is expected when the database is being accessed concurrently. The retry will likely succeed so it is pointless to warn immediately. Instead we track how long each retrySQLite block has been running, and only begin warning after a second has elapsed (and then every 10 seconds subsequently).
This commit is contained in:
parent
7f5ca6192d
commit
7c56e84213
|
@ -239,14 +239,9 @@ SQLiteTxn::~SQLiteTxn()
|
|||
}
|
||||
}
|
||||
|
||||
void handleSQLiteBusy(const SQLiteBusy & e)
|
||||
void handleSQLiteBusy(const SQLiteBusy & e, bool shouldWarn)
|
||||
{
|
||||
static std::atomic<time_t> lastWarned{0};
|
||||
|
||||
time_t now = time(0);
|
||||
|
||||
if (now > lastWarned + 10) {
|
||||
lastWarned = now;
|
||||
if (shouldWarn) {
|
||||
logWarning({
|
||||
.msg = hintfmt(e.what())
|
||||
});
|
||||
|
|
|
@ -139,7 +139,7 @@ protected:
|
|||
|
||||
MakeError(SQLiteBusy, SQLiteError);
|
||||
|
||||
void handleSQLiteBusy(const SQLiteBusy & e);
|
||||
void handleSQLiteBusy(const SQLiteBusy & e, bool shouldWarn);
|
||||
|
||||
/**
|
||||
* Convenience function for retrying a SQLite transaction when the
|
||||
|
@ -148,11 +148,22 @@ void handleSQLiteBusy(const SQLiteBusy & e);
|
|||
template<typename T, typename F>
|
||||
T retrySQLite(F && fun)
|
||||
{
|
||||
time_t nextWarning = time(0) + 1;
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
return fun();
|
||||
|
||||
} catch (SQLiteBusy & e) {
|
||||
handleSQLiteBusy(e);
|
||||
time_t now = time(0);
|
||||
bool shouldWarn = false;
|
||||
|
||||
if (now > nextWarning) {
|
||||
nextWarning = now + 10;
|
||||
shouldWarn = true;
|
||||
}
|
||||
|
||||
handleSQLiteBusy(e, shouldWarn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue