Commit 4f79c509 authored by Daniel Vrátil's avatar Daniel Vrátil 🤖
Browse files

akonadi_control: cleanup

parent 18f70493
......@@ -23,12 +23,13 @@
#include "agenttype.h"
#include "agentmanager.h"
AgentInstance::AgentInstance(AgentManager *manager)
: QObject(manager)
, mManager(manager)
AgentInstance::AgentInstance(AgentManager &manager)
: mManager(manager)
{
}
AgentInstance::~AgentInstance() = default;
void AgentInstance::quit()
{
if (mAgentControlInterface && mAgentControlInterface->isValid()) {
......@@ -47,13 +48,8 @@ void AgentInstance::cleanup()
bool AgentInstance::obtainAgentInterface()
{
delete mAgentControlInterface;
delete mAgentStatusInterface;
mAgentControlInterface =
findInterface<org::freedesktop::Akonadi::Agent::Control>(Akonadi::DBus::Agent, "/");
mAgentStatusInterface =
findInterface<org::freedesktop::Akonadi::Agent::Status>(Akonadi::DBus::Agent, "/");
mAgentControlInterface = findInterface<org::freedesktop::Akonadi::Agent::Control>(Akonadi::DBus::Agent, "/");
mAgentStatusInterface = findInterface<org::freedesktop::Akonadi::Agent::Status>(Akonadi::DBus::Agent, "/");
if (mPendingQuit && mAgentControlInterface && mAgentControlInterface->isValid()) {
mAgentControlInterface->quit();
......@@ -67,12 +63,13 @@ bool AgentInstance::obtainAgentInterface()
mSearchInterface =
findInterface<org::freedesktop::Akonadi::Agent::Search>(Akonadi::DBus::Agent, "/Search");
connect(mAgentStatusInterface, SIGNAL(status(int,QString)), SLOT(statusChanged(int,QString)));
connect(mAgentStatusInterface, &OrgFreedesktopAkonadiAgentStatusInterface::advancedStatus, this, &AgentInstance::advancedStatusChanged);
connect(mAgentStatusInterface, &OrgFreedesktopAkonadiAgentStatusInterface::percent, this, &AgentInstance::percentChanged);
connect(mAgentStatusInterface, &OrgFreedesktopAkonadiAgentStatusInterface::warning, this, &AgentInstance::warning);
connect(mAgentStatusInterface, &OrgFreedesktopAkonadiAgentStatusInterface::error, this, &AgentInstance::error);
connect(mAgentStatusInterface, &OrgFreedesktopAkonadiAgentStatusInterface::onlineChanged, this, &AgentInstance::onlineChanged);
connect(mAgentStatusInterface.get(), qOverload<int, const QString &>(&OrgFreedesktopAkonadiAgentStatusInterface::status),
this, &AgentInstance::statusChanged);
connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::advancedStatus, this, &AgentInstance::advancedStatusChanged);
connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::percent, this, &AgentInstance::percentChanged);
connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::warning, this, &AgentInstance::warning);
connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::error, this, &AgentInstance::error);
connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::onlineChanged, this, &AgentInstance::onlineChanged);
refreshAgentStatus();
return true;
......@@ -80,25 +77,21 @@ bool AgentInstance::obtainAgentInterface()
bool AgentInstance::obtainResourceInterface()
{
delete mResourceInterface;
mResourceInterface =
findInterface<org::freedesktop::Akonadi::Resource>(Akonadi::DBus::Resource, "/");
mResourceInterface = findInterface<org::freedesktop::Akonadi::Resource>(Akonadi::DBus::Resource, "/");
if (!mResourceInterface) {
return false;
}
connect(mResourceInterface, &OrgFreedesktopAkonadiResourceInterface::nameChanged, this, &AgentInstance::resourceNameChanged);
connect(mResourceInterface.get(), &OrgFreedesktopAkonadiResourceInterface::nameChanged, this, &AgentInstance::resourceNameChanged);
refreshResourceStatus();
return true;
}
bool AgentInstance::obtainPreprocessorInterface()
{
delete mPreprocessorInterface;
mPreprocessorInterface =
findInterface<org::freedesktop::Akonadi::Preprocessor>(Akonadi::DBus::Preprocessor, "/");
return mPreprocessorInterface;
mPreprocessorInterface = findInterface<org::freedesktop::Akonadi::Preprocessor>(Akonadi::DBus::Preprocessor, "/");
return mPreprocessorInterface != nullptr;
}
void AgentInstance::statusChanged(int status, const QString &statusMsg)
......@@ -108,12 +101,12 @@ void AgentInstance::statusChanged(int status, const QString &statusMsg)
}
mStatus = status;
mStatusMessage = statusMsg;
Q_EMIT mManager->agentInstanceStatusChanged(mIdentifier, mStatus, mStatusMessage);
Q_EMIT mManager.agentInstanceStatusChanged(mIdentifier, mStatus, mStatusMessage);
}
void AgentInstance::advancedStatusChanged(const QVariantMap &status)
{
Q_EMIT mManager->agentInstanceAdvancedStatusChanged(mIdentifier, status);
Q_EMIT mManager.agentInstanceAdvancedStatusChanged(mIdentifier, status);
}
void AgentInstance::statusStateChanged(int status)
......@@ -132,17 +125,17 @@ void AgentInstance::percentChanged(int percent)
return;
}
mPercent = percent;
Q_EMIT mManager->agentInstanceProgressChanged(mIdentifier, mPercent, QString());
Q_EMIT mManager.agentInstanceProgressChanged(mIdentifier, mPercent, QString());
}
void AgentInstance::warning(const QString &msg)
{
Q_EMIT mManager->agentInstanceWarning(mIdentifier, msg);
Q_EMIT mManager.agentInstanceWarning(mIdentifier, msg);
}
void AgentInstance::error(const QString &msg)
{
Q_EMIT mManager->agentInstanceError(mIdentifier, msg);
Q_EMIT mManager.agentInstanceError(mIdentifier, msg);
}
void AgentInstance::onlineChanged(bool state)
......@@ -151,7 +144,7 @@ void AgentInstance::onlineChanged(bool state)
return;
}
mOnline = state;
Q_EMIT mManager->agentInstanceOnlineChanged(mIdentifier, state);
Q_EMIT mManager.agentInstanceOnlineChanged(mIdentifier, state);
}
void AgentInstance::resourceNameChanged(const QString &name)
......@@ -160,7 +153,7 @@ void AgentInstance::resourceNameChanged(const QString &name)
return;
}
mResourceName = name;
Q_EMIT mManager->agentInstanceNameChanged(mIdentifier, name);
Q_EMIT mManager.agentInstanceNameChanged(mIdentifier, name);
}
void AgentInstance::refreshAgentStatus()
......@@ -204,17 +197,16 @@ void AgentInstance::errorHandler(const QDBusError &error)
}
template <typename T>
T *AgentInstance::findInterface(Akonadi::DBus::AgentType agentType, const char *path)
std::unique_ptr<T> AgentInstance::findInterface(Akonadi::DBus::AgentType agentType, const char *path)
{
T *iface = new T(Akonadi::DBus::agentServiceName(mIdentifier, agentType),
QLatin1String(path), QDBusConnection::sessionBus(), this);
auto iface = std::make_unique<T>(Akonadi::DBus::agentServiceName(mIdentifier, agentType),
QLatin1String(path), QDBusConnection::sessionBus(), this);
if (!iface || !iface->isValid()) {
qCCritical(AKONADICONTROL_LOG) << Q_FUNC_INFO << "Cannot connect to agent instance with identifier"
<< mIdentifier << ", error message:"
<< (iface ? iface->lastError().message() : QString());
delete iface;
return nullptr;
iface.release();
}
return iface;
}
......@@ -32,6 +32,8 @@
#include <QSharedPointer>
#include <QString>
#include <memory>
class AgentManager;
class AgentType;
......@@ -49,10 +51,8 @@ class AgentInstance : public QObject
public:
typedef QSharedPointer<AgentInstance> Ptr;
explicit AgentInstance(AgentManager *manager);
virtual ~AgentInstance()
{
}
explicit AgentInstance(AgentManager &manager);
~AgentInstance() override;
/** Set/get the unique identifier of this AgentInstance */
Q_REQUIRED_RESULT QString identifier() const
......@@ -103,42 +103,42 @@ public:
Q_REQUIRED_RESULT bool hasResourceInterface() const
{
return mResourceInterface;
return mResourceInterface != nullptr;
}
Q_REQUIRED_RESULT bool hasAgentInterface() const
{
return mAgentControlInterface && mAgentStatusInterface;
return mAgentControlInterface != nullptr && mAgentStatusInterface != nullptr;
}
Q_REQUIRED_RESULT bool hasPreprocessorInterface() const
{
return mPreprocessorInterface;
return mPreprocessorInterface != nullptr;
}
org::freedesktop::Akonadi::Agent::Control *controlInterface() const
{
return mAgentControlInterface;
return mAgentControlInterface.get();
}
org::freedesktop::Akonadi::Agent::Status *statusInterface() const
{
return mAgentStatusInterface;
return mAgentStatusInterface.get();
}
org::freedesktop::Akonadi::Agent::Search *searchInterface() const
{
return mSearchInterface;
return mSearchInterface.get();
}
org::freedesktop::Akonadi::Resource *resourceInterface() const
{
return mResourceInterface;
return mResourceInterface.get();
}
org::freedesktop::Akonadi::Preprocessor *preProcessorInterface() const
{
return mPreprocessorInterface;
return mPreprocessorInterface.get();
}
bool obtainAgentInterface();
......@@ -162,7 +162,8 @@ protected Q_SLOTS:
void errorHandler(const QDBusError &error);
private:
template <typename T> T *findInterface(Akonadi::DBus::AgentType agentType, const char *path = nullptr);
template <typename T>
std::unique_ptr<T> findInterface(Akonadi::DBus::AgentType agentType, const char *path = nullptr);
protected:
void setAgentType(const QString &agentType)
......@@ -173,17 +174,17 @@ protected:
private:
QString mIdentifier;
QString mType;
AgentManager *mManager = nullptr;
org::freedesktop::Akonadi::Agent::Control *mAgentControlInterface = nullptr;
org::freedesktop::Akonadi::Agent::Status *mAgentStatusInterface = nullptr;
org::freedesktop::Akonadi::Agent::Search *mSearchInterface = nullptr;
org::freedesktop::Akonadi::Resource *mResourceInterface = nullptr;
org::freedesktop::Akonadi::Preprocessor *mPreprocessorInterface = nullptr;
AgentManager &mManager;
std::unique_ptr<org::freedesktop::Akonadi::Agent::Control> mAgentControlInterface;
std::unique_ptr<org::freedesktop::Akonadi::Agent::Status> mAgentStatusInterface;
std::unique_ptr<org::freedesktop::Akonadi::Agent::Search> mSearchInterface;
std::unique_ptr<org::freedesktop::Akonadi::Resource> mResourceInterface;
std::unique_ptr<org::freedesktop::Akonadi::Preprocessor> mPreprocessorInterface;
int mStatus = 0;
QString mResourceName;
QString mStatusMessage;
int mStatus = 0;
int mPercent = 0;
QString mResourceName;
bool mOnline = false;
bool mPendingQuit = false;
......
......@@ -45,9 +45,58 @@
#include <QDBusConnection>
using Akonadi::ProcessControl;
using namespace std::chrono_literals;
static const bool enableAgentServerDefault = false;
class StorageProcessControl : public Akonadi::ProcessControl
{
Q_OBJECT
public:
StorageProcessControl(const QStringList &args)
: Akonadi::ProcessControl()
{
setShutdownTimeout(15s);
connect(this, &Akonadi::ProcessControl::unableToStart, this,
[]() {
QCoreApplication::instance()->exit(255);
});
start(QStringLiteral("akonadiserver"), args, RestartOnCrash);
}
~StorageProcessControl() override
{
setCrashPolicy(ProcessControl::StopOnCrash);
org::freedesktop::Akonadi::Server serverIface(Akonadi::DBus::serviceName(Akonadi::DBus::Server), QStringLiteral("/Server"),
QDBusConnection::sessionBus());
serverIface.quit();
}
};
class AgentServerProcessControl : public Akonadi::ProcessControl
{
Q_OBJECT
public:
AgentServerProcessControl(const QStringList &args)
: Akonadi::ProcessControl()
{
connect(this, &Akonadi::ProcessControl::unableToStart, this,
[]() {
qCCritical(AKONADICONTROL_LOG) << "Failed to start AgentServer!";
});
start(QStringLiteral("akonadi_agent_server"), args, RestartOnCrash);
}
~AgentServerProcessControl() override
{
setCrashPolicy(ProcessControl::StopOnCrash);
org::freedesktop::Akonadi::AgentServer agentServerIface(Akonadi::DBus::serviceName(Akonadi::DBus::AgentServer),
QStringLiteral("/AgentServer"), QDBusConnection::sessionBus(), this);
agentServerIface.quit();
}
};
AgentManager::AgentManager(bool verbose, QObject *parent)
: QObject(parent)
, mAgentServer(nullptr)
......@@ -75,15 +124,10 @@ AgentManager::AgentManager(bool verbose, QObject *parent)
serviceArgs << QStringLiteral("--verbose");
}
mStorageController = new Akonadi::ProcessControl;
mStorageController->setShutdownTimeout(15 * 1000); // the server needs more time for shutdown if we are using an internal mysqld
connect(mStorageController, &Akonadi::ProcessControl::unableToStart, this, &AgentManager::serverFailure);
mStorageController->start(QStringLiteral("akonadiserver"), serviceArgs, Akonadi::ProcessControl::RestartOnCrash);
mStorageController = std::unique_ptr<Akonadi::ProcessControl>(new StorageProcessControl(serviceArgs));
if (mAgentServerEnabled) {
mAgentServer = new Akonadi::ProcessControl;
connect(mAgentServer, &Akonadi::ProcessControl::unableToStart, this, &AgentManager::agentServerFailure);
mAgentServer->start(QStringLiteral("akonadi_agent_server"), serviceArgs, Akonadi::ProcessControl::RestartOnCrash);
mAgentServer = std::unique_ptr<Akonadi::ProcessControl>(new AgentServerProcessControl(serviceArgs));
}
}
......@@ -127,28 +171,10 @@ void AgentManager::cleanup()
for (const AgentInstance::Ptr &instance : qAsConst(mAgentInstances)) {
instance->quit();
}
mAgentInstances.clear();
mStorageController->setCrashPolicy(ProcessControl::StopOnCrash);
org::freedesktop::Akonadi::Server *serverIface =
new org::freedesktop::Akonadi::Server(Akonadi::DBus::serviceName(Akonadi::DBus::Server), QStringLiteral("/Server"),
QDBusConnection::sessionBus(), this);
serverIface->quit();
if (mAgentServer) {
mAgentServer->setCrashPolicy(ProcessControl::StopOnCrash);
org::freedesktop::Akonadi::AgentServer *agentServerIface =
new org::freedesktop::Akonadi::AgentServer(Akonadi::DBus::serviceName(Akonadi::DBus::AgentServer),
QStringLiteral("/AgentServer"), QDBusConnection::sessionBus(), this);
agentServerIface->quit();
}
delete mStorageController;
mStorageController = nullptr;
delete mAgentServer;
mAgentServer = nullptr;
mStorageController.reset();
mStorageController.reset();
}
QStringList AgentManager::agentTypes() const
......@@ -218,10 +244,10 @@ AgentInstance::Ptr AgentManager::createAgentInstance(const AgentType &info)
{
switch (info.launchMethod) {
case AgentType::Server:
return AgentInstance::Ptr(new Akonadi::AgentThreadInstance(this));
return QSharedPointer<Akonadi::AgentThreadInstance>::create(*this);
case AgentType::Launcher: // Fall through
case AgentType::Process:
return AgentInstance::Ptr(new Akonadi::AgentProcessInstance(this));
return QSharedPointer<Akonadi::AgentProcessInstance>::create(*this);
default:
Q_ASSERT_X(false, "AgentManger::createAgentInstance", "Unhandled AgentType::LaunchMethod case");
}
......@@ -235,10 +261,10 @@ QString AgentManager::createAgentInstance(const QString &identifier)
return QString();
}
const AgentType agentInfo = mAgents.value(identifier);
mAgents[identifier].instanceCounter++;
AgentType &agentInfo = mAgents[identifier];
agentInfo.instanceCounter++;
const AgentInstance::Ptr instance = createAgentInstance(agentInfo);
const auto instance = createAgentInstance(agentInfo);
if (agentInfo.capabilities.contains(AgentType::CapabilityUnique)) {
instance->setIdentifier(identifier);
} else {
......@@ -270,7 +296,7 @@ QString AgentManager::createAgentInstance(const QString &identifier)
void AgentManager::removeAgentInstance(const QString &identifier)
{
const AgentInstance::Ptr instance = mAgentInstances.value(identifier);
const auto instance = mAgentInstances.value(identifier);
if (!instance) {
qCWarning(AKONADICONTROL_LOG) << Q_FUNC_INFO << "Agent instance with identifier" << identifier << "does not exist";
return;
......@@ -856,14 +882,4 @@ void AgentManager::removeSearch(quint64 resultCollectionId)
}
}
void AgentManager::agentServerFailure()
{
qCCritical(AKONADICONTROL_LOG) << "Failed to start AgentServer!";
// if ( requiresAgentServer )
// QCoreApplication::instance()->exit( 255 );
}
void AgentManager::serverFailure()
{
QCoreApplication::instance()->exit(255);
}
#include "agentmanager.moc"
......@@ -325,8 +325,6 @@ private Q_SLOTS:
void updatePluginInfos();
void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
void agentExeChanged(const QString &fileName);
void agentServerFailure();
void serverFailure();
private:
/**
......@@ -382,10 +380,10 @@ private:
*/
QHash<QString, AgentInstance::Ptr> mAgentInstances;
Akonadi::ProcessControl *mAgentServer = nullptr;
Akonadi::ProcessControl *mStorageController = nullptr;
bool mAgentServerEnabled;
bool mVerbose;
std::unique_ptr<Akonadi::ProcessControl> mAgentServer;
std::unique_ptr<Akonadi::ProcessControl> mStorageController;
bool mAgentServerEnabled = false;
bool mVerbose = false;
friend class AgentInstance;
};
......
......@@ -28,7 +28,7 @@
using namespace Akonadi;
AgentProcessInstance::AgentProcessInstance(AgentManager *manager)
AgentProcessInstance::AgentProcessInstance(AgentManager &manager)
: AgentInstance(manager)
{
}
......@@ -53,8 +53,8 @@ bool AgentProcessInstance::start(const AgentType &agentInfo)
return false;
}
mController = new Akonadi::ProcessControl(this);
connect(mController, &ProcessControl::unableToStart, this, &AgentProcessInstance::failedToStart);
mController = std::make_unique<Akonadi::ProcessControl>();
connect(mController.get(), &ProcessControl::unableToStart, this, &AgentProcessInstance::failedToStart);
if (agentInfo.launchMethod == AgentType::Process) {
const QStringList arguments = { QStringLiteral("--identifier"), identifier()};
......
......@@ -33,8 +33,9 @@ class AgentProcessInstance : public AgentInstance
Q_OBJECT
public:
explicit AgentProcessInstance(AgentManager *manager);
~AgentProcessInstance() override {}
explicit AgentProcessInstance(AgentManager &manager);
~AgentProcessInstance() override = default;
bool start(const AgentType &agentInfo) override;
void quit() override;
void cleanup() override;
......@@ -45,7 +46,7 @@ private Q_SLOTS:
void failedToStart();
private:
Akonadi::ProcessControl *mController = nullptr;
std::unique_ptr<Akonadi::ProcessControl> mController;
};
}
......
......@@ -24,17 +24,14 @@
#include <private/dbus_p.h>
#include <QDBusServiceWatcher>
using namespace Akonadi;
AgentThreadInstance::AgentThreadInstance(AgentManager *manager)
AgentThreadInstance::AgentThreadInstance(AgentManager &manager)
: AgentInstance(manager)
, mServiceWatcher(Akonadi::DBus::serviceName(Akonadi::DBus::AgentServer),
QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration)
{
QDBusServiceWatcher *watcher = new QDBusServiceWatcher(Akonadi::DBus::serviceName(Akonadi::DBus::AgentServer),
QDBusConnection::sessionBus(),
QDBusServiceWatcher::WatchForRegistration, this);
connect(watcher, &QDBusServiceWatcher::serviceRegistered,
connect(&mServiceWatcher, &QDBusServiceWatcher::serviceRegistered,
this, &AgentThreadInstance::agentServerRegistered);
}
......@@ -49,7 +46,7 @@ bool AgentThreadInstance::start(const AgentType &agentInfo)
mAgentType = agentInfo;
org::freedesktop::Akonadi::AgentServer agentServer(Akonadi::DBus::serviceName(Akonadi::DBus::AgentServer),
QStringLiteral("/AgentServer"), QDBusConnection::sessionBus());
QStringLiteral("/AgentServer"), QDBusConnection::sessionBus());
if (!agentServer.isValid()) {
qCDebug(AKONADICONTROL_LOG) << "AgentServer not up (yet?)";
return false;
......@@ -65,7 +62,7 @@ void AgentThreadInstance::quit()
AgentInstance::quit();
org::freedesktop::Akonadi::AgentServer agentServer(Akonadi::DBus::serviceName(Akonadi::DBus::AgentServer),
QStringLiteral("/AgentServer"), QDBusConnection::sessionBus());
QStringLiteral("/AgentServer"), QDBusConnection::sessionBus());
agentServer.stopAgent(identifier());
}
......@@ -73,7 +70,7 @@ void AgentThreadInstance::restartWhenIdle()
{
if (status() != 1 && !identifier().isEmpty()) {
org::freedesktop::Akonadi::AgentServer agentServer(Akonadi::DBus::serviceName(Akonadi::DBus::AgentServer),
QStringLiteral("/AgentServer"), QDBusConnection::sessionBus());
QStringLiteral("/AgentServer"), QDBusConnection::sessionBus());
agentServer.stopAgent(identifier());
agentServer.startAgent(identifier(), agentType(), mAgentType.exec);
}
......@@ -87,6 +84,6 @@ void AgentThreadInstance::agentServerRegistered()
void Akonadi::AgentThreadInstance::configure(qlonglong windowId)
{
org::freedesktop::Akonadi::AgentServer agentServer(Akonadi::DBus::serviceName(Akonadi::DBus::AgentServer),
QStringLiteral("/AgentServer"), QDBusConnection::sessionBus());
QStringLiteral("/AgentServer"), QDBusConnection::sessionBus());
agentServer.agentInstanceConfigure(identifier(), windowId);
}
......@@ -22,6 +22,8 @@
#include "agentinstance.h"
#include "agenttype.h"
#include <QDBusServiceWatcher>
namespace Akonadi
{
......@@ -29,8 +31,8 @@ class AgentThreadInstance : public AgentInstance
{
Q_OBJECT
public:
explicit AgentThreadInstance(AgentManager *manager);
~AgentThreadInstance() override {}
explicit AgentThreadInstance(AgentManager &manager);
~AgentThreadInstance() override = default;
bool start(const AgentType &agentInfo) override;
void quit() override;
......@@ -42,6 +44,7 @@ private Q_SLOTS:
private:
AgentType mAgentType;
QDBusServiceWatcher mServiceWatcher;
};
}
......
......@@ -33,6 +33,7 @@
#endif
using namespace Akonadi;
using namespace std::chrono_literals;
static const int s_maxCrashCount = 2;
......@@ -42,7 +43,7 @@ ProcessControl::ProcessControl(QObject *parent)
, mFailedToStart(false)
, mCrashCount(0)
, mRestartOnceOnExit(false)
, mShutdownTimeout(1000)
, mShutdownTimeout(1s)
{
connect(&mProcess, &QProcess::errorOccurred,
this, &ProcessControl::slotError);
......@@ -84,7 +85,7 @@ void ProcessControl::setCrashPolicy(CrashPolicy policy)
void ProcessControl::stop()
{
if (mProcess.state() != QProcess::NotRunning) {
mProcess.waitForFinished(mShutdownTimeout);
mProcess.waitForFinished(mShutdownTimeout.count());