mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-22 13:15:39 +08:00
refs #756 Fixed session cache concept:
Each new session generates an ID identifying that session, and the .rev file annotates the ID associated with each cache value. This is needed to avoid reading a value from a previous session when loading for a continuing (non-new) session. The coarse- grained approach of distinguishing new sessions from non-new sessions was insufficient.
This commit is contained in:
committed by
Klaus Basan
parent
937cdbcc55
commit
d0d1a9c8b8
@@ -335,10 +335,10 @@ namespace BlackMisc
|
|||||||
public:
|
public:
|
||||||
Session(const QString &filename) : m_filename(filename) {}
|
Session(const QString &filename) : m_filename(filename) {}
|
||||||
void updateSession();
|
void updateSession();
|
||||||
bool isNewSession() const { return m_isNewSession; }
|
const QUuid &uuid() const { return m_uuid; }
|
||||||
private:
|
private:
|
||||||
const QString m_filename;
|
const QString m_filename;
|
||||||
bool m_isNewSession = false;
|
QUuid m_uuid;
|
||||||
};
|
};
|
||||||
|
|
||||||
CDataCacheRevision::CDataCacheRevision(const QString &basename) : m_basename(basename), m_session(std::make_unique<Session>(m_basename + "/.session")) {}
|
CDataCacheRevision::CDataCacheRevision(const QString &basename) : m_basename(basename), m_session(std::make_unique<Session>(m_basename + "/.session")) {}
|
||||||
@@ -421,9 +421,11 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_session->updateSession();
|
m_session->updateSession();
|
||||||
if (isNewSession())
|
auto sessionIds = sessionFromJson(json.value("session").toObject());
|
||||||
|
for (auto it = sessionIds.cbegin(); it != sessionIds.cend(); ++it)
|
||||||
{
|
{
|
||||||
for (const auto &key : fromJson(json.value("session").toArray())) { m_timestamps.remove(key); }
|
m_sessionValues[it.key()] = it.value();
|
||||||
|
if (it.value() != m_session->uuid()) { m_timestamps.remove(it.key()); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (revisionFile.size() > 0)
|
else if (revisionFile.size() > 0)
|
||||||
@@ -461,6 +463,11 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
for (const auto &key : excludeKeys) { timestamps.remove(key); }
|
for (const auto &key : excludeKeys) { timestamps.remove(key); }
|
||||||
|
|
||||||
|
for (auto it = timestamps.cbegin(); it != timestamps.cend(); ++it)
|
||||||
|
{
|
||||||
|
if (m_sessionValues.contains(it.key())) { m_sessionValues[it.key()] = m_session->uuid(); }
|
||||||
|
}
|
||||||
|
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
json.insert("uuid", m_uuid.toString());
|
json.insert("uuid", m_uuid.toString());
|
||||||
json.insert("timestamps", toJson(timestamps));
|
json.insert("timestamps", toJson(timestamps));
|
||||||
@@ -681,16 +688,7 @@ namespace BlackMisc
|
|||||||
QMutexLocker lock(&m_mutex);
|
QMutexLocker lock(&m_mutex);
|
||||||
|
|
||||||
Q_ASSERT(! m_updateInProgress);
|
Q_ASSERT(! m_updateInProgress);
|
||||||
m_sessionValues.insert(key);
|
m_sessionValues[key]; // insert default-constructed value, unless key already present
|
||||||
}
|
|
||||||
|
|
||||||
bool CDataCacheRevision::isNewSession() const
|
|
||||||
{
|
|
||||||
QMutexLocker lock(&m_mutex);
|
|
||||||
|
|
||||||
Q_ASSERT(m_updateInProgress);
|
|
||||||
Q_ASSERT(m_session);
|
|
||||||
return m_session->isNewSession();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject CDataCacheRevision::toJson(const QMap<QString, qint64> ×tamps)
|
QJsonObject CDataCacheRevision::toJson(const QMap<QString, qint64> ×tamps)
|
||||||
@@ -733,6 +731,26 @@ namespace BlackMisc
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject CDataCacheRevision::toJson(const QMap<QString, QUuid> ×tamps)
|
||||||
|
{
|
||||||
|
QJsonObject result;
|
||||||
|
for (auto it = timestamps.begin(); it != timestamps.end(); ++it)
|
||||||
|
{
|
||||||
|
result.insert(it.key(), it.value().toString());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, QUuid> CDataCacheRevision::sessionFromJson(const QJsonObject &session)
|
||||||
|
{
|
||||||
|
QMap<QString, QUuid> result;
|
||||||
|
for (auto it = session.begin(); it != session.end(); ++it)
|
||||||
|
{
|
||||||
|
result.insert(it.key(), QUuid(it.value().toString()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void CDataCacheRevision::Session::updateSession()
|
void CDataCacheRevision::Session::updateSession()
|
||||||
{
|
{
|
||||||
CAtomicFile file(m_filename);
|
CAtomicFile file(m_filename);
|
||||||
@@ -740,19 +758,23 @@ namespace BlackMisc
|
|||||||
if (! ok)
|
if (! ok)
|
||||||
{
|
{
|
||||||
CLogMessage(this).error("Failed to open session file %1: %2") << m_filename << file.errorString();
|
CLogMessage(this).error("Failed to open session file %1: %2") << m_filename << file.errorString();
|
||||||
m_isNewSession = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CSequence<CProcessInfo> session;
|
auto json = QJsonDocument::fromJson(file.readAll()).object();
|
||||||
session.convertFromJson(file.readAll());
|
QUuid uuid(json.value("uuid").toString());
|
||||||
session.removeIf([](const CProcessInfo &pi) { return ! pi.exists(); });
|
CSequence<CProcessInfo> apps;
|
||||||
|
apps.convertFromJson(json.value("apps").toObject());
|
||||||
|
apps.removeIf([](const CProcessInfo &pi) { return ! pi.exists(); });
|
||||||
|
|
||||||
m_isNewSession = session.isEmpty();
|
if (apps.isEmpty()) { uuid = CIdentifier().toUuid(); }
|
||||||
|
m_uuid = uuid;
|
||||||
|
|
||||||
CProcessInfo currentProcess = CProcessInfo::currentProcess();
|
CProcessInfo currentProcess = CProcessInfo::currentProcess();
|
||||||
Q_ASSERT(currentProcess.exists());
|
Q_ASSERT(currentProcess.exists());
|
||||||
session.replaceOrAdd(currentProcess, currentProcess);
|
apps.replaceOrAdd(currentProcess, currentProcess);
|
||||||
if (!(file.seek(0) && file.resize(0) && file.write(QJsonDocument(session.toJson()).toJson()) && file.checkedClose()))
|
json.insert("apps", apps.toJson());
|
||||||
|
json.insert("uuid", uuid.toString());
|
||||||
|
if (!(file.seek(0) && file.resize(0) && file.write(QJsonDocument(json).toJson()) && file.checkedClose()))
|
||||||
{
|
{
|
||||||
CLogMessage(this).error("Failed to write to session file %1: %2") << m_filename << file.errorString();
|
CLogMessage(this).error("Failed to write to session file %1: %2") << m_filename << file.errorString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,9 +162,6 @@ namespace BlackMisc
|
|||||||
//! Set the flag which will cause a value to be reset when starting a new session.
|
//! Set the flag which will cause a value to be reset when starting a new session.
|
||||||
void sessionValue(const QString &key);
|
void sessionValue(const QString &key);
|
||||||
|
|
||||||
//! True if the current update is the first of a new session.
|
|
||||||
bool isNewSession() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QMutex m_mutex { QMutex::Recursive };
|
mutable QMutex m_mutex { QMutex::Recursive };
|
||||||
bool m_updateInProgress = false;
|
bool m_updateInProgress = false;
|
||||||
@@ -180,7 +177,7 @@ namespace BlackMisc
|
|||||||
QSet<QString> m_deferredValues;
|
QSet<QString> m_deferredValues;
|
||||||
QSet<QString> m_admittedValues;
|
QSet<QString> m_admittedValues;
|
||||||
QSet<QString> m_admittedQueue;
|
QSet<QString> m_admittedQueue;
|
||||||
QSet<QString> m_sessionValues;
|
QMap<QString, QUuid> m_sessionValues;
|
||||||
std::vector<std::promise<void>> m_promises;
|
std::vector<std::promise<void>> m_promises;
|
||||||
|
|
||||||
class Session;
|
class Session;
|
||||||
@@ -190,6 +187,8 @@ namespace BlackMisc
|
|||||||
static QMap<QString, qint64> fromJson(const QJsonObject ×tamps);
|
static QMap<QString, qint64> fromJson(const QJsonObject ×tamps);
|
||||||
static QJsonArray toJson(const QSet<QString> &pins);
|
static QJsonArray toJson(const QSet<QString> &pins);
|
||||||
static QSet<QString> fromJson(const QJsonArray &pins);
|
static QSet<QString> fromJson(const QJsonArray &pins);
|
||||||
|
static QJsonObject toJson(const QMap<QString, QUuid> &session);
|
||||||
|
static QMap<QString, QUuid> sessionFromJson(const QJsonObject &session);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
Reference in New Issue
Block a user