forked from lix-project/lix
[PDT] TDE-3114: prevent a race-condition when creating the S3 cache
This commit is contained in:
parent
1437582ccd
commit
bc8ab21c5a
|
@ -166,16 +166,37 @@ public:
|
||||||
return i->second;
|
return i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<Cache> queryCacheRaw(State & state, const std::string & uri)
|
||||||
|
{
|
||||||
|
auto i = state.caches.find(uri);
|
||||||
|
if (i == state.caches.end()) {
|
||||||
|
auto queryCache(state.queryCache.use()(uri)(time(0) - cacheInfoTtl));
|
||||||
|
if (!queryCache.next())
|
||||||
|
return std::nullopt;
|
||||||
|
state.caches.emplace(uri,
|
||||||
|
Cache{(int) queryCache.getInt(0), queryCache.getStr(1), queryCache.getInt(2) != 0, (int) queryCache.getInt(3)});
|
||||||
|
}
|
||||||
|
return getCache(state, uri);
|
||||||
|
}
|
||||||
|
|
||||||
void createCache(const std::string & uri, const Path & storeDir, bool wantMassQuery, int priority) override
|
void createCache(const std::string & uri, const Path & storeDir, bool wantMassQuery, int priority) override
|
||||||
{
|
{
|
||||||
retrySQLite<void>([&]() {
|
retrySQLite<void>([&]() {
|
||||||
auto state(_state.lock());
|
auto state(_state.lock());
|
||||||
|
SQLiteTxn txn(state->db);
|
||||||
|
|
||||||
// FIXME: race
|
// To avoid the race, we have to check if maybe someone hasn't yet created
|
||||||
|
// the cache for this URI in the meantime.
|
||||||
|
auto cache(queryCacheRaw(*state, uri));
|
||||||
|
|
||||||
|
if (cache)
|
||||||
|
return;
|
||||||
|
|
||||||
state->insertCache.use()(uri)(time(0))(storeDir)(wantMassQuery)(priority).exec();
|
state->insertCache.use()(uri)(time(0))(storeDir)(wantMassQuery)(priority).exec();
|
||||||
assert(sqlite3_changes(state->db) == 1);
|
assert(sqlite3_changes(state->db) == 1);
|
||||||
state->caches[uri] = Cache{(int) sqlite3_last_insert_rowid(state->db), storeDir, wantMassQuery, priority};
|
state->caches[uri] = Cache{(int) sqlite3_last_insert_rowid(state->db), storeDir, wantMassQuery, priority};
|
||||||
|
|
||||||
|
txn.commit();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,21 +204,12 @@ public:
|
||||||
{
|
{
|
||||||
return retrySQLite<std::optional<CacheInfo>>([&]() -> std::optional<CacheInfo> {
|
return retrySQLite<std::optional<CacheInfo>>([&]() -> std::optional<CacheInfo> {
|
||||||
auto state(_state.lock());
|
auto state(_state.lock());
|
||||||
|
auto cache(queryCacheRaw(*state, uri));
|
||||||
auto i = state->caches.find(uri);
|
if (!cache)
|
||||||
if (i == state->caches.end()) {
|
return std::nullopt;
|
||||||
auto queryCache(state->queryCache.use()(uri)(time(0) - cacheInfoTtl));
|
|
||||||
if (!queryCache.next())
|
|
||||||
return std::nullopt;
|
|
||||||
state->caches.emplace(uri,
|
|
||||||
Cache{(int) queryCache.getInt(0), queryCache.getStr(1), queryCache.getInt(2) != 0, (int) queryCache.getInt(3)});
|
|
||||||
}
|
|
||||||
|
|
||||||
auto & cache(getCache(*state, uri));
|
|
||||||
|
|
||||||
return CacheInfo {
|
return CacheInfo {
|
||||||
.wantMassQuery = cache.wantMassQuery,
|
.wantMassQuery = cache->wantMassQuery,
|
||||||
.priority = cache.priority
|
.priority = cache->priority
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue