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"
@ 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)
KJob(QObject *parent=nullptr)
QString i18n(const char *text, const TYPE &arg...)
Helper integration between Akonadi and Qt.
bool isValid(QStringView ifopt)
QDBusConnection sessionBus()
QObject(QObject *parent)
QObject * parent() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void timeout()
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:49:57 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.