Utils: Remove PresistentStoreCache

It turns out caching the information is unreliable due to a variety of reasons.
We remove the cache for now as its less dangerous than trying to fix each
use case.

Change-Id: I8238166486a2fb29c101f700af1c8d7e4ad7a172
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Marcus Tillmanns
2024-03-12 14:24:06 +01:00
parent 07399dfb0c
commit 4e8bdd610b
8 changed files with 12 additions and 192 deletions

View File

@@ -117,7 +117,6 @@ add_qtc_library(Utils
passworddialog.cpp passworddialog.h
pathchooser.cpp pathchooser.h
pathlisteditor.cpp pathlisteditor.h
persistentcachestore.cpp persistentcachestore.h
persistentsettings.cpp persistentsettings.h
pointeralgorithm.h
port.cpp port.h

View File

@@ -1,115 +0,0 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "persistentcachestore.h"
#include "filepath.h"
#include "fileutils.h"
#include <QMap>
#include <QMutex>
#include <QStandardPaths>
namespace Utils {
class PrivateGlobal
{
public:
QMutex mutex;
QMap<Key, Store> caches;
};
static expected_str<FilePath> cacheFolder()
{
static const FilePath folder = FilePath::fromUserInput(QStandardPaths::writableLocation(
QStandardPaths::CacheLocation))
/ "CachedStores";
static expected_str<void> created = folder.ensureWritableDir();
static expected_str<FilePath> result = created ? folder
: expected_str<FilePath>(
make_unexpected(created.error()));
QTC_ASSERT_EXPECTED(result, return result);
return result;
}
static PrivateGlobal &globals()
{
static PrivateGlobal global;
return global;
}
static expected_str<FilePath> filePathFromKey(const Key &cacheKey)
{
static const expected_str<FilePath> folder = cacheFolder();
if (!folder)
return folder;
return (*folder / FileUtils::fileSystemFriendlyName(stringFromKey(cacheKey))).withSuffix(".json");
}
expected_str<Store> PersistentCacheStore::byKey(const Key &cacheKey)
{
const expected_str<FilePath> path = filePathFromKey(cacheKey);
if (!path)
return make_unexpected(path.error());
QMutexLocker locker(&globals().mutex);
auto it = globals().caches.find(cacheKey);
if (it != globals().caches.end())
return it.value();
const expected_str<QByteArray> contents = path->fileContents();
if (!contents)
return make_unexpected(contents.error());
auto result = storeFromJson(*contents);
if (!result)
return result;
if (result->value("__cache_key__").toString() != stringFromKey(cacheKey)) {
return make_unexpected(QString("Cache key mismatch: \"%1\" to \"%2\" in \"%3\".")
.arg(stringFromKey(cacheKey))
.arg(result->value("__cache_key__").toString())
.arg(path->toUserOutput()));
}
return result;
}
expected_str<void> PersistentCacheStore::write(const Key &cacheKey, const Store &store)
{
const expected_str<FilePath> path = filePathFromKey(cacheKey);
if (!path)
return make_unexpected(path.error());
QMutexLocker locker(&globals().mutex);
globals().caches.insert(cacheKey, store);
// TODO: The writing of the store data could be done in a separate thread in the future.
Store storeCopy = store;
storeCopy.insert("__cache_key__", stringFromKey(cacheKey));
storeCopy.insert("__last_modified__", QDateTime::currentDateTime().toString(Qt::ISODate));
QByteArray json = jsonFromStore(storeCopy);
const expected_str<qint64> result = path->writeFileContents(json);
if (!result)
return make_unexpected(result.error());
return {};
}
expected_str<void> PersistentCacheStore::clear(const Key &cacheKey)
{
const expected_str<FilePath> path = filePathFromKey(cacheKey);
if (!path)
return make_unexpected(path.error());
QMutexLocker locker(&globals().mutex);
globals().caches.remove(cacheKey);
if (!path->removeFile())
return make_unexpected(QString("Failed to remove cache file."));
return {};
}
} // namespace Utils

View File

@@ -1,22 +0,0 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "utils_global.h"
#include "expected.h"
#include "store.h"
#include "storekey.h"
namespace Utils {
class QTCREATOR_UTILS_EXPORT PersistentCacheStore
{
public:
static expected_str<Store> byKey(const Key &cacheKey);
static expected_str<void> write(const Key &cacheKey, const Store &store);
static expected_str<void> clear(const Key &cacheKey);
};
} // namespace Utils

View File

@@ -115,7 +115,7 @@ public:
CMakeTool cmake(m_autodetected ? CMakeTool::AutoDetection
: CMakeTool::ManualDetection, m_id);
cmake.setFilePath(m_executable);
m_isSupported = cmake.hasFileApi(true);
m_isSupported = cmake.hasFileApi();
m_tooltip = Tr::tr("Version: %1").arg(cmake.versionDisplay());
m_tooltip += "<br>" + Tr::tr("Supports fileApi: %1").arg(m_isSupported ? Tr::tr("yes") : Tr::tr("no"));

View File

@@ -11,7 +11,6 @@
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/persistentcachestore.h>
#include <utils/process.h>
#include <utils/qtcassert.h>
#include <utils/temporarydirectory.h>
@@ -155,13 +154,13 @@ FilePath CMakeTool::filePath() const
return m_executable;
}
bool CMakeTool::isValid(bool ignoreCache) const
bool CMakeTool::isValid() const
{
if (!m_id.isValid() || !m_introspection)
return false;
if (!m_introspection->m_didAttemptToRun)
readInformation(ignoreCache);
readInformation();
return m_introspection->m_haveCapabilitites && !m_introspection->m_fileApis.isEmpty();
}
@@ -324,9 +323,9 @@ CMakeKeywords CMakeTool::keywords()
return m_introspection->m_keywords;
}
bool CMakeTool::hasFileApi(bool ignoreCache) const
bool CMakeTool::hasFileApi() const
{
return isValid(ignoreCache) ? !m_introspection->m_fileApis.isEmpty() : false;
return isValid() ? !m_introspection->m_fileApis.isEmpty() : false;
}
CMakeTool::Version CMakeTool::version() const
@@ -438,7 +437,7 @@ void CMakeTool::openCMakeHelpUrl(const CMakeTool *tool, const QString &linkUrl)
Core::HelpManager::showHelpUrl(linkUrl.arg(documentationUrl(version, online)));
}
void CMakeTool::readInformation(bool ignoreCache) const
void CMakeTool::readInformation() const
{
QTC_ASSERT(m_introspection, return );
if (!m_introspection->m_haveCapabilitites && m_introspection->m_didAttemptToRun)
@@ -446,7 +445,7 @@ void CMakeTool::readInformation(bool ignoreCache) const
m_introspection->m_didAttemptToRun = true;
fetchFromCapabilities(ignoreCache);
fetchFromCapabilities();
}
@@ -625,17 +624,8 @@ QStringList CMakeTool::parseSyntaxHighlightingXml()
return moduleFunctions;
}
void CMakeTool::fetchFromCapabilities(bool ignoreCache) const
void CMakeTool::fetchFromCapabilities() const
{
expected_str<Utils::Store> cache = PersistentCacheStore::byKey(
keyFromString("CMake_" + cmakeExecutable().toUserOutput()));
if (cache && !ignoreCache) {
m_introspection->m_haveCapabilitites = true;
parseFromCapabilities(cache->value("CleanedStdOut").toString());
return;
}
Process cmake;
runCMake(cmake, {"-E", "capabilities"});
@@ -646,12 +636,6 @@ void CMakeTool::fetchFromCapabilities(bool ignoreCache) const
qCCritical(cmakeToolLog) << "Fetching capabilities failed: " << cmake.allOutput() << cmake.error();
m_introspection->m_haveCapabilitites = false;
}
Store newData{{"CleanedStdOut", cmake.cleanedStdOut()}};
const auto result
= PersistentCacheStore::write(keyFromString("CMake_" + cmakeExecutable().toUserOutput()),
newData);
QTC_ASSERT_EXPECTED(result, return);
}
static int getVersion(const QVariantMap &obj, const QString &value)

View File

@@ -74,7 +74,7 @@ public:
static Utils::Id createId();
bool isValid(bool ignoreCache = false) const;
bool isValid() const;
Utils::Id id() const { return m_id; }
Utils::Store toMap () const;
@@ -91,7 +91,7 @@ public:
bool autoCreateBuildDirectory() const;
QList<Generator> supportedGenerators() const;
CMakeKeywords keywords();
bool hasFileApi(bool ignoreCache = false) const;
bool hasFileApi() const;
Version version() const;
QString versionDisplay() const;
@@ -113,14 +113,14 @@ public:
static void openCMakeHelpUrl(const CMakeTool *tool, const QString &linkUrl);
private:
void readInformation(bool ignoreCache = false) const;
void readInformation() const;
void runCMake(Utils::Process &proc, const QStringList &args, int timeoutS = 1) const;
void parseFunctionDetailsOutput(const QString &output);
QStringList parseVariableOutput(const QString &output);
QStringList parseSyntaxHighlightingXml();
void fetchFromCapabilities(bool ignoreCache = false) const;
void fetchFromCapabilities() const;
void parseFromCapabilities(const QString &input) const;
// Note: New items here need also be handled in CMakeToolItemModel::apply()

View File

@@ -19,7 +19,6 @@
#include <utils/algorithm.h>
#include <utils/mimeutils.h>
#include <utils/persistentcachestore.h>
#include <utils/process.h>
#include <QReadLocker>
@@ -201,20 +200,10 @@ static bool isUsableHelper(QHash<FilePath, bool> *cache, const QString &keyStrin
auto it = cache->find(python);
if (it == cache->end()) {
const Key key = keyFromString(keyString);
const auto store = PersistentCacheStore::byKey(key);
if (store && store->value(keyFromString(python.toString())).toBool()) {
cache->insert(python, true);
return true;
}
Process process;
process.setCommand({python, QStringList{"-m", commandArg, "-h"}});
process.runBlocking();
const bool usable = process.result() == ProcessResult::FinishedWithSuccess;
if (usable) {
Store newStore = store.value_or(Store{});
newStore.insert(keyFromString(python.toString()), true);
PersistentCacheStore::write(key, newStore);
}
it = cache->insert(python, usable);
}
return *it;

View File

@@ -33,7 +33,6 @@
#include <utils/fileinprojectfinder.h>
#include <utils/hostosinfo.h>
#include <utils/macroexpander.h>
#include <utils/persistentcachestore.h>
#include <utils/process.h>
#include <utils/qtcassert.h>
#include <utils/stringutils.h>
@@ -768,12 +767,6 @@ void QtVersion::fromMap(const Store &map, const FilePath &filePath, bool forceRe
}
d->m_qmakeCommand = filePath.resolvePath(d->m_qmakeCommand);
const expected_str<Utils::Store> persistentStore = PersistentCacheStore::byKey(
Key("QtVersionData" + d->m_qmakeCommand.toString().toUtf8()));
if (persistentStore && !forceRefreshCache)
d->m_data.fromMap(*persistentStore);
Store::const_iterator itQtAbis = map.find(QTVERSION_ABIS);
if (itQtAbis != map.end()) {
// Only the SDK Tool writes abis to the settings. If we find abis in the settings, we want
@@ -804,11 +797,6 @@ Store QtVersion::toMap() const
result.insert(QTVERSIONQMAKEPATH, qmakeFilePath().toSettings());
if (d->m_data.versionInfoUpToDate) {
PersistentCacheStore::write(Key("QtVersionData" + d->m_qmakeCommand.toString().toUtf8()),
d->m_data.toMap());
}
return result;
}
@@ -1419,9 +1407,6 @@ void QtVersionPrivate::updateVersionInfo()
m_isUpdating = false;
m_data.versionInfoUpToDate = true;
PersistentCacheStore::write(Key("QtVersionData" + m_qmakeCommand.toString().toUtf8()),
m_data.toMap());
}
QHash<ProKey,ProString> QtVersionPrivate::versionInfo()