Update Octree to atomically persist data

This commit is contained in:
Ryan Huffman 2018-06-13 12:07:20 -07:00
parent 6b159d6124
commit c2f08dfdba
4 changed files with 12 additions and 32 deletions

View file

@ -1207,8 +1207,8 @@ void OctreeServer::beginRunning() {
beforeRun(); // after payload has been processed beforeRun(); // after payload has been processed
connect(nodeList.data(), &NodeList::nodeAdded, &OctreeServer::nodeAdded); connect(nodeList.data(), &NodeList::nodeAdded, this, &OctreeServer::nodeAdded);
connect(nodeList.data(), &NodeList::nodeKilled, &OctreeServer::nodeKilled); connect(nodeList.data(), &NodeList::nodeKilled, this, &OctreeServer::nodeKilled);
nodeList->linkedDataCreateCallback = [this](Node* node) { nodeList->linkedDataCreateCallback = [this](Node* node) {
auto queryNodeData = createOctreeQueryNode(); auto queryNodeData = createOctreeQueryNode();

View file

@ -30,6 +30,7 @@
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray> #include <QJsonArray>
#include <QFileInfo> #include <QFileInfo>
#include <QSaveFile>
#include <QString> #include <QString>
#include <QRegularExpression> #include <QRegularExpression>
#include <QRegularExpressionMatch> #include <QRegularExpressionMatch>
@ -972,10 +973,12 @@ bool Octree::writeToJSONFile(const char* fileName, const OctreeElementPointer& e
return false; return false;
} }
QFile persistFile(fileName); QSaveFile persistFile(fileName);
bool success = false; bool success = false;
if (persistFile.open(QIODevice::WriteOnly)) { if (persistFile.open(QIODevice::WriteOnly)) {
success = persistFile.write(jsonDataForFile) != -1; if (persistFile.write(jsonDataForFile) != -1) {
success = persistFile.commit();
}
} else { } else {
qCritical("Could not write to JSON description of entities."); qCritical("Could not write to JSON description of entities.");
} }

View file

@ -62,19 +62,6 @@ OctreePersistThread::OctreePersistThread(OctreePointer tree, const QString& file
void OctreePersistThread::start() { void OctreePersistThread::start() {
cleanupOldReplacementBackups(); cleanupOldReplacementBackups();
QFile tempFile { getTempFilename() };
if (tempFile.exists()) {
qWarning(octree) << "Found temporary octree file at" << tempFile.fileName();
qDebug(octree) << "Attempting to recover from temporary octree file";
QFile::remove(_filename);
if (tempFile.rename(_filename)) {
qDebug(octree) << "Successfully recovered from temporary octree file";
} else {
qWarning(octree) << "Failed to recover from temporary octree file";
tempFile.remove();
}
}
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver(); auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::OctreeDataFileReply, this, "handleOctreeDataFileReply"); packetReceiver.registerListener(PacketType::OctreeDataFileReply, this, "handleOctreeDataFileReply");
@ -182,7 +169,7 @@ void OctreePersistThread::handleOctreeDataFileReply(QSharedPointer<ReceivedMessa
_initialLoadComplete = true; _initialLoadComplete = true;
// Since we just loaded the persistent file, we can consider ourselves as having just persist // Since we just loaded the persistent file, we can consider ourselves as having just persisted
_lastPersistCheck = std::chrono::steady_clock::now(); _lastPersistCheck = std::chrono::steady_clock::now();
if (replacementData.isNull()) { if (replacementData.isNull()) {
@ -305,20 +292,12 @@ void OctreePersistThread::persist() {
_tree->incrementPersistDataVersion(); _tree->incrementPersistDataVersion();
QString tempFilename = getTempFilename(); qCDebug(octree) << "Saving Octree data to:" << _filename;
qCDebug(octree) << "Saving temporary Octree file to:" << tempFilename; if (_tree->writeToFile(_filename.toLocal8Bit().constData(), nullptr, _persistAsFileType)) {
if (_tree->writeToFile(tempFilename.toLocal8Bit().constData(), nullptr, _persistAsFileType)) {
QFile tempFile { tempFilename };
_tree->clearDirtyBit(); // tree is clean after saving _tree->clearDirtyBit(); // tree is clean after saving
QFile::remove(_filename); qCDebug(octree) << "DONE persisting Octree data to" << _filename;
if (tempFile.rename(_filename)) {
qCDebug(octree) << "DONE moving temporary Octree file to" << _filename;
} else {
qCWarning(octree) << "Failed to move temporary Octree file to " << _filename;
tempFile.remove();
}
} else { } else {
qCWarning(octree) << "Failed to open temp Octree file at" << tempFilename; qCWarning(octree) << "Failed to persist Octree data to" << _filename;
} }
sendLatestEntityDataToDS(); sendLatestEntityDataToDS();

View file

@ -65,8 +65,6 @@ protected:
void replaceData(QByteArray data); void replaceData(QByteArray data);
void sendLatestEntityDataToDS(); void sendLatestEntityDataToDS();
QString getTempFilename() const { return _filename + ".temp"; }
private: private:
OctreePointer _tree; OctreePointer _tree;
QString _filename; QString _filename;