From 44744e281a56488c7ef257e12ca379ec4ceb2cdd Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 8 Feb 2016 21:34:06 +0100 Subject: Executed database removal in the resource instead of the client. The resource doesn't really notify all clients properly about the removal, but the tests all still pass. --- common/clientapi.cpp | 22 ++++++++++++++++------ common/clientapi.h | 5 +++++ common/commands.cpp | 2 ++ common/commands.h | 1 + common/genericresource.cpp | 6 ++++++ common/genericresource.h | 1 + common/listener.cpp | 8 ++++++++ common/resource.cpp | 5 +++++ common/resource.h | 5 +++++ common/storage.h | 7 +++++++ common/storage_lmdb.cpp | 8 ++++++++ 11 files changed, 64 insertions(+), 6 deletions(-) (limited to 'common') diff --git a/common/clientapi.cpp b/common/clientapi.cpp index 5eb4b55..73bc194 100644 --- a/common/clientapi.cpp +++ b/common/clientapi.cpp @@ -197,12 +197,22 @@ KAsync::Job Store::start(const QByteArray &identifier) void Store::removeFromDisk(const QByteArray &identifier) { - //TODO By calling the resource executable with a --remove option instead - //we can ensure that no other resource process is running at the same time - QDir dir(Sink::storageLocation()); - for (const auto &folder : dir.entryList(QStringList() << identifier + "*")) { - Sink::Storage(Sink::storageLocation(), folder, Sink::Storage::ReadWrite).removeFromDisk(); - } + removeDataFromDisk(identifier).exec().waitForFinished(); +} + +KAsync::Job Store::removeDataFromDisk(const QByteArray &identifier) +{ + //All databases are going to become invalid, nuke the environments + //TODO: all clients should react to a notification the resource + Sink::Storage::clearEnv(); + Trace() << "Remove data from disk " << identifier; + auto time = QSharedPointer::create(); + time->start(); + auto resourceAccess = QSharedPointer::create(identifier); + resourceAccess->open(); + return resourceAccess->sendCommand(Sink::Commands::RemoveFromDiskCommand).then([resourceAccess, time]() { + Trace() << "Remove from disk complete." << Log::TraceTime(time->elapsed()); + }); } KAsync::Job Store::synchronize(const Sink::Query &query) diff --git a/common/clientapi.h b/common/clientapi.h index d0910df..45c5390 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -110,6 +110,11 @@ public: */ static void removeFromDisk(const QByteArray &resourceIdentifier); + /** + * Removes a resource from disk. + */ + static KAsync::Job removeDataFromDisk(const QByteArray &resourceIdentifier); + template static KAsync::Job fetchOne(const Sink::Query &query); diff --git a/common/commands.cpp b/common/commands.cpp index 8b915f0..5d38afa 100644 --- a/common/commands.cpp +++ b/common/commands.cpp @@ -61,6 +61,8 @@ QByteArray name(int commandId) return "RevisionReplayed"; case InspectionCommand: return "Inspection"; + case RemoveFromDiskCommand: + return "RemoveFromDisk"; case CustomCommand: return "Custom"; }; diff --git a/common/commands.h b/common/commands.h index fa4712b..adf2094 100644 --- a/common/commands.h +++ b/common/commands.h @@ -48,6 +48,7 @@ enum CommandIds { PingCommand, RevisionReplayedCommand, InspectionCommand, + RemoveFromDiskCommand, CustomCommand = 0xffff }; diff --git a/common/genericresource.cpp b/common/genericresource.cpp index 6087896..c097893 100644 --- a/common/genericresource.cpp +++ b/common/genericresource.cpp @@ -396,12 +396,18 @@ KAsync::Job GenericResource::replay(Sink::Storage &synchronizationStore, c return KAsync::null(); } +void GenericResource::removeDataFromDisk() +{ + removeFromDisk(mResourceInstanceIdentifier); +} + void GenericResource::removeFromDisk(const QByteArray &instanceIdentifier) { Sink::Storage(Sink::storageLocation(), instanceIdentifier, Sink::Storage::ReadWrite).removeFromDisk(); Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".userqueue", Sink::Storage::ReadWrite).removeFromDisk(); Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronizerqueue", Sink::Storage::ReadWrite).removeFromDisk(); Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".changereplay", Sink::Storage::ReadWrite).removeFromDisk(); + Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::ReadWrite).removeFromDisk(); } qint64 GenericResource::diskUsage(const QByteArray &instanceIdentifier) diff --git a/common/genericresource.h b/common/genericresource.h index 1bbb0f5..ae505a6 100644 --- a/common/genericresource.h +++ b/common/genericresource.h @@ -52,6 +52,7 @@ public: int error() const; + void removeDataFromDisk() Q_DECL_OVERRIDE; static void removeFromDisk(const QByteArray &instanceIdentifier); static qint64 diskUsage(const QByteArray &instanceIdentifier); diff --git a/common/listener.cpp b/common/listener.cpp index 323252b..d2fa266 100644 --- a/common/listener.cpp +++ b/common/listener.cpp @@ -275,6 +275,14 @@ void Listener::processCommand(int commandId, uint messageId, const QByteArray &c loadResource()->setLowerBoundRevision(lowerBoundRevision()); } break; + case Sink::Commands::RemoveFromDiskCommand: { + Log() << QString("\tReceived a remove from disk command from %1").arg(client.name); + m_resource->removeDataFromDisk(); + delete m_resource; + m_resource = nullptr; + loadResource()->setLowerBoundRevision(0); + } + break; default: if (commandId > Sink::Commands::CustomCommand) { Log() << QString("\tReceived custom command from %1: ").arg(client.name) << commandId; diff --git a/common/resource.cpp b/common/resource.cpp index 6972efe..5cbb2f2 100644 --- a/common/resource.cpp +++ b/common/resource.cpp @@ -63,6 +63,11 @@ void Resource::setLowerBoundRevision(qint64 revision) Q_UNUSED(revision) } +void Resource::removeDataFromDisk() +{ +} + + class ResourceFactory::Private { public: diff --git a/common/resource.h b/common/resource.h index f6ca039..368759c 100644 --- a/common/resource.h +++ b/common/resource.h @@ -55,6 +55,11 @@ public: */ virtual void setLowerBoundRevision(qint64 revision); + /** + * Remove the data from disk + */ + virtual void removeDataFromDisk(); + Q_SIGNALS: void revisionUpdated(qint64); void notify(Notification); diff --git a/common/storage.h b/common/storage.h index 84175b3..8ec3f1d 100644 --- a/common/storage.h +++ b/common/storage.h @@ -180,6 +180,13 @@ public: qint64 diskUsage() const; void removeFromDisk() const; + /** + * Clears all cached environments. + * + * This only ever has to be called if a database was removed from another process. + */ + static void clearEnv(); + static qint64 maxRevision(const Sink::Storage::Transaction &); static void setMaxRevision(Sink::Storage::Transaction &, qint64 revision); diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp index e2c623e..1efffc4 100644 --- a/common/storage_lmdb.cpp +++ b/common/storage_lmdb.cpp @@ -615,4 +615,12 @@ void Storage::removeFromDisk() const mdb_env_close(env); } +void Storage::clearEnv() +{ + for (auto env : Storage::Private::sEnvironments) { + mdb_env_close(env); + } + Storage::Private::sEnvironments.clear(); +} + } // namespace Sink -- cgit v1.2.3