mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-23 05:45:35 +08:00
refs #581, #592 Allow to renew a stale value by updating the timestamp on disk without altering the value.
This commit is contained in:
@@ -105,6 +105,11 @@ namespace BlackMisc
|
|||||||
QTimer::singleShot(0, &m_serializer, [this, key, ttl] { m_revision.setTimeToLive(key, ttl); });
|
QTimer::singleShot(0, &m_serializer, [this, key, ttl] { m_revision.setTimeToLive(key, ttl); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDataCache::renewTimestamp(const QString &key, qint64 timestamp)
|
||||||
|
{
|
||||||
|
QTimer::singleShot(0, &m_serializer, [this, key, timestamp] { m_revision.overrideTimestamp(key, timestamp); });
|
||||||
|
}
|
||||||
|
|
||||||
QString lockFileError(const QLockFile &lock)
|
QString lockFileError(const QLockFile &lock)
|
||||||
{
|
{
|
||||||
switch (lock.error())
|
switch (lock.error())
|
||||||
@@ -385,6 +390,41 @@ namespace BlackMisc
|
|||||||
m_timesToLive.insert(key, ttl);
|
m_timesToLive.insert(key, ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDataCacheRevision::overrideTimestamp(const QString &key, qint64 timestamp)
|
||||||
|
{
|
||||||
|
Q_ASSERT(! m_updateInProgress);
|
||||||
|
Q_ASSERT(! m_lockFile.isLocked());
|
||||||
|
|
||||||
|
if (! m_lockFile.lock())
|
||||||
|
{
|
||||||
|
CLogMessage(this).error("Failed to lock %1: %2") << m_basename << lockFileError(m_lockFile);
|
||||||
|
m_lockFile.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAtomicFile revisionFile(m_basename + "/.rev");
|
||||||
|
if (revisionFile.exists())
|
||||||
|
{
|
||||||
|
if (! revisionFile.open(QFile::ReadWrite | QFile::Text))
|
||||||
|
{
|
||||||
|
CLogMessage(this).error("Failed to open %1: %2") << revisionFile.fileName() << revisionFile.errorString();
|
||||||
|
m_lockFile.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto json = QJsonDocument::fromJson(revisionFile.readAll()).object();
|
||||||
|
auto timestamps = json.value("timestamps").toObject();
|
||||||
|
timestamps.insert(key, timestamp);
|
||||||
|
json.insert("timestamps", timestamps);
|
||||||
|
|
||||||
|
if (! (revisionFile.seek(0) && revisionFile.resize(0) && revisionFile.write(QJsonDocument(json).toJson()) && revisionFile.checkedClose()))
|
||||||
|
{
|
||||||
|
CLogMessage(this).error("Failed to write to %1: %2") << revisionFile.fileName() << revisionFile.errorString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_lockFile.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
QJsonObject CDataCacheRevision::toJson(const QMap<QString, qint64> ×tamps)
|
QJsonObject CDataCacheRevision::toJson(const QMap<QString, qint64> ×tamps)
|
||||||
{
|
{
|
||||||
QJsonObject result;
|
QJsonObject result;
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ namespace BlackMisc
|
|||||||
//! Set TTL value that will be written to the revision file.
|
//! Set TTL value that will be written to the revision file.
|
||||||
void setTimeToLive(const QString &key, int ttl);
|
void setTimeToLive(const QString &key, int ttl);
|
||||||
|
|
||||||
|
//! Causes the new timestamp to be written to the revision file.
|
||||||
|
void overrideTimestamp(const QString &key, qint64 timestamp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QMutex m_mutex { QMutex::Recursive };
|
mutable QMutex m_mutex { QMutex::Recursive };
|
||||||
bool m_updateInProgress = false;
|
bool m_updateInProgress = false;
|
||||||
@@ -157,6 +160,9 @@ namespace BlackMisc
|
|||||||
//! Method used for implementing TTL.
|
//! Method used for implementing TTL.
|
||||||
void setTimeToLive(const QString &key, int ttl);
|
void setTimeToLive(const QString &key, int ttl);
|
||||||
|
|
||||||
|
//! Method used for implementing timestamp renewal.
|
||||||
|
void renewTimestamp(const QString &key, qint64 timestamp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CDataCache();
|
CDataCache();
|
||||||
|
|
||||||
@@ -204,6 +210,9 @@ namespace BlackMisc
|
|||||||
//! True if the current timestamp is older than the TTL (time to live).
|
//! True if the current timestamp is older than the TTL (time to live).
|
||||||
bool isStale() const { return this->getTimestamp() + Trait::timeToLive() > QDateTime::currentMSecsSinceEpoch(); }
|
bool isStale() const { return this->getTimestamp() + Trait::timeToLive() > QDateTime::currentMSecsSinceEpoch(); }
|
||||||
|
|
||||||
|
//! Don't change the value, but write a new timestamp, to extend the life of the value.
|
||||||
|
void renewTimestamp(qint64 timestamp) { return CDataCache::instance()->renewTimestamp(this->getKey(), timestamp); }
|
||||||
|
|
||||||
//! Return a future providing the value. If the value is still loading, the future will wait for it.
|
//! Return a future providing the value. If the value is still loading, the future will wait for it.
|
||||||
//! If the value is not present, the variant is null. Bypasses async get and inhibits notification slot.
|
//! If the value is not present, the variant is null. Bypasses async get and inhibits notification slot.
|
||||||
std::future<CVariant> syncLoad() { return CDataCache::instance()->syncLoad(m_owner, this->getKey()); }
|
std::future<CVariant> syncLoad() { return CDataCache::instance()->syncLoad(m_owner, this->getKey()); }
|
||||||
|
|||||||
Reference in New Issue
Block a user