Akonadi

collectionattributessynchronizationjob.cpp
1/*
2 * SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6
7#include "collectionattributessynchronizationjob.h"
8#include "akonadicore_debug.h"
9#include "kjobprivatebase_p.h"
10#include "servermanager.h"
11#include <QDBusConnection>
12
13#include "agentinstance.h"
14#include "agentmanager.h"
15#include "collection.h"
16
17#include <KLocalizedString>
18
19#include <QDBusInterface>
20#include <QTimer>
21
22namespace Akonadi
23{
24class CollectionAttributesSynchronizationJobPrivate : public KJobPrivateBase
25{
26 Q_OBJECT
27
28public:
29 explicit CollectionAttributesSynchronizationJobPrivate(CollectionAttributesSynchronizationJob *parent)
30 : q(parent)
31 {
32 connect(&safetyTimer, &QTimer::timeout, this, &CollectionAttributesSynchronizationJobPrivate::slotTimeout);
33 safetyTimer.setInterval(std::chrono::seconds{5});
34 safetyTimer.setSingleShot(false);
35 }
36
37 void doStart() override;
38
39 CollectionAttributesSynchronizationJob *const q;
40 AgentInstance instance;
41 Collection collection;
42 QDBusInterface *interface = nullptr;
43 QTimer safetyTimer;
44 int timeoutCount = 0;
45 static const int timeoutCountLimit;
46
47private Q_SLOTS:
48 void slotSynchronized(qlonglong /*id*/);
49 void slotTimeout();
50};
51
52const int CollectionAttributesSynchronizationJobPrivate::timeoutCountLimit = 2;
53
55 : KJob(parent)
56 , d(new CollectionAttributesSynchronizationJobPrivate(this))
57{
58 d->instance = AgentManager::self()->instance(collection.resource());
59 d->collection = collection;
60}
61
63
64void CollectionAttributesSynchronizationJob::start()
65{
66 d->start();
67}
68
69void CollectionAttributesSynchronizationJobPrivate::doStart()
70{
71 if (!collection.isValid()) {
72 q->setError(KJob::UserDefinedError);
73 q->setErrorText(i18n("Invalid collection instance."));
74 q->emitResult();
75 return;
76 }
77
78 if (!instance.isValid()) {
79 q->setError(KJob::UserDefinedError);
80 q->setErrorText(i18n("Invalid resource instance."));
81 q->emitResult();
82 return;
83 }
84
85 interface = new QDBusInterface(ServerManager::agentServiceName(ServerManager::Resource, instance.identifier()),
86 QStringLiteral("/"),
87 QStringLiteral("org.freedesktop.Akonadi.Resource"),
89 this);
90 connect(interface, SIGNAL(attributesSynchronized(qlonglong)), this, SLOT(slotSynchronized(qlonglong))); // clazy:exclude=old-style-connect
91
92 if (interface->isValid()) {
93 const QDBusMessage reply = interface->call(QStringLiteral("synchronizeCollectionAttributes"), collection.id());
94 if (reply.type() == QDBusMessage::ErrorMessage) {
95 // This means that the resource doesn't provide a synchronizeCollectionAttributes method, so we just finish the job
96 q->emitResult();
97 return;
98 }
99 safetyTimer.start();
100 } else {
101 q->setError(KJob::UserDefinedError);
102 q->setErrorText(i18n("Unable to obtain D-Bus interface for resource '%1'", instance.identifier()));
103 q->emitResult();
104 return;
105 }
106}
107
108void CollectionAttributesSynchronizationJobPrivate::slotSynchronized(qlonglong id)
109{
110 if (id == collection.id()) {
111 disconnect(interface, SIGNAL(attributesSynchronized(qlonglong)), this, SLOT(slotSynchronized(qlonglong))); // clazy:exclude=old-style-connect
112 safetyTimer.stop();
113 q->emitResult();
114 }
115}
116
117void CollectionAttributesSynchronizationJobPrivate::slotTimeout()
118{
119 instance = AgentManager::self()->instance(instance.identifier());
120 timeoutCount++;
121
122 if (timeoutCount > timeoutCountLimit) {
123 safetyTimer.stop();
124 q->setError(KJob::UserDefinedError);
125 q->setErrorText(i18n("Collection attributes synchronization timed out."));
126 q->emitResult();
127 return;
128 }
129
130 if (instance.status() == AgentInstance::Idle) {
131 // try again, we might have lost the synchronized() signal
132 qCDebug(AKONADICORE_LOG) << "collection attributes" << collection.id() << instance.identifier();
133 interface->call(QStringLiteral("synchronizeCollectionAttributes"), collection.id());
134 }
135}
136
137} // namespace Akonadi
138
139#include "collectionattributessynchronizationjob.moc"
140
141#include "moc_collectionattributessynchronizationjob.cpp"
Represents one agent instance and takes care of communication with it.
Status status() const
Returns the status of the agent instance.
bool isValid() const
Returns whether the agent instance object is valid.
QString identifier() const
Returns the unique identifier of the agent instance.
@ Idle
The agent instance does currently nothing.
static AgentManager * self()
Returns the global instance of the agent manager.
AgentInstance instance(const QString &identifier) const
Returns the agent instance with the given identifier or an invalid agent instance if the identifier d...
CollectionAttributesSynchronizationJob(const Collection &collection, QObject *parent=nullptr)
Creates a new synchronization job for the given collection.
~CollectionAttributesSynchronizationJob() override
Destroys the synchronization job.
Represents a collection of PIM items.
Definition collection.h:62
void setErrorText(const QString &errorText)
void emitResult()
void setError(int errorCode)
QString i18n(const char *text, const TYPE &arg...)
Helper integration between Akonadi and Qt.
bool isValid(QStringView ifopt)
QDBusMessage call(QDBus::CallMode mode, const QString &method, Args &&... args)
QDBusConnection sessionBus()
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setInterval(int msec)
void setSingleShot(bool singleShot)
void stop()
void timeout()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:38 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.