Convenience macros for retrying a SQLite transaction
This commit is contained in:
parent
bce14d0f61
commit
4bd5282573
1 changed files with 42 additions and 46 deletions
|
@ -75,6 +75,11 @@ static void throwSQLiteError(sqlite3 * db, const format & f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Convenience macros for retrying a SQLite transaction. */
|
||||||
|
#define retry_sqlite while (1) { try {
|
||||||
|
#define end_retry_sqlite break; } catch (SQLiteBusy & e) { } }
|
||||||
|
|
||||||
|
|
||||||
SQLite::~SQLite()
|
SQLite::~SQLite()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -1219,39 +1224,33 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
|
||||||
* expense of some speed of the path registering operation. */
|
* expense of some speed of the path registering operation. */
|
||||||
if (settings.syncBeforeRegistering) sync();
|
if (settings.syncBeforeRegistering) sync();
|
||||||
|
|
||||||
while (1) {
|
retry_sqlite {
|
||||||
try {
|
SQLiteTxn txn(db);
|
||||||
SQLiteTxn txn(db);
|
PathSet paths;
|
||||||
PathSet paths;
|
|
||||||
|
|
||||||
foreach (ValidPathInfos::const_iterator, i, infos) {
|
foreach (ValidPathInfos::const_iterator, i, infos) {
|
||||||
assert(i->hash.type == htSHA256);
|
assert(i->hash.type == htSHA256);
|
||||||
if (isValidPath(i->path))
|
if (isValidPath(i->path))
|
||||||
updatePathInfo(*i);
|
updatePathInfo(*i);
|
||||||
else
|
else
|
||||||
addValidPath(*i);
|
addValidPath(*i);
|
||||||
paths.insert(i->path);
|
paths.insert(i->path);
|
||||||
}
|
|
||||||
|
|
||||||
foreach (ValidPathInfos::const_iterator, i, infos) {
|
|
||||||
unsigned long long referrer = queryValidPathId(i->path);
|
|
||||||
foreach (PathSet::iterator, j, i->references)
|
|
||||||
addReference(referrer, queryValidPathId(*j));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do a topological sort of the paths. This will throw an
|
|
||||||
error if a cycle is detected and roll back the
|
|
||||||
transaction. Cycles can only occur when a derivation
|
|
||||||
has multiple outputs. */
|
|
||||||
topoSortPaths(*this, paths);
|
|
||||||
|
|
||||||
txn.commit();
|
|
||||||
break;
|
|
||||||
} catch (SQLiteBusy & e) {
|
|
||||||
/* Retry; the `txn' destructor will roll back the current
|
|
||||||
transaction. */
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
foreach (ValidPathInfos::const_iterator, i, infos) {
|
||||||
|
unsigned long long referrer = queryValidPathId(i->path);
|
||||||
|
foreach (PathSet::iterator, j, i->references)
|
||||||
|
addReference(referrer, queryValidPathId(*j));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do a topological sort of the paths. This will throw an
|
||||||
|
error if a cycle is detected and roll back the
|
||||||
|
transaction. Cycles can only occur when a derivation
|
||||||
|
has multiple outputs. */
|
||||||
|
topoSortPaths(*this, paths);
|
||||||
|
|
||||||
|
txn.commit();
|
||||||
|
} end_retry_sqlite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1642,23 +1641,20 @@ void LocalStore::invalidatePathChecked(const Path & path)
|
||||||
{
|
{
|
||||||
assertStorePath(path);
|
assertStorePath(path);
|
||||||
|
|
||||||
while (1) {
|
retry_sqlite {
|
||||||
try {
|
SQLiteTxn txn(db);
|
||||||
SQLiteTxn txn(db);
|
|
||||||
|
|
||||||
if (isValidPath(path)) {
|
if (isValidPath(path)) {
|
||||||
PathSet referrers; queryReferrers(path, referrers);
|
PathSet referrers; queryReferrers(path, referrers);
|
||||||
referrers.erase(path); /* ignore self-references */
|
referrers.erase(path); /* ignore self-references */
|
||||||
if (!referrers.empty())
|
if (!referrers.empty())
|
||||||
throw PathInUse(format("cannot delete path `%1%' because it is in use by %2%")
|
throw PathInUse(format("cannot delete path `%1%' because it is in use by %2%")
|
||||||
% path % showPaths(referrers));
|
% path % showPaths(referrers));
|
||||||
invalidatePath(path);
|
invalidatePath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
txn.commit();
|
txn.commit();
|
||||||
break;
|
} end_retry_sqlite;
|
||||||
} catch (SQLiteBusy & e) { };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue