Akonadi

resourcesynchronizationjob.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 "resourcesynchronizationjob.h"
8#include "agentinstance.h"
9#include "agentmanager.h"
10#include "akonadicore_debug.h"
11#include "kjobprivatebase_p.h"
12#include "resourceinterface.h"
13#include "servermanager.h"
14#include <QDBusConnection>
15
16#include <KLocalizedString>
17
18#include <QDBusInterface>
19#include <QTimer>
20
21namespace Akonadi
22{
23class ResourceSynchronizationJobPrivate : public KJobPrivateBase
24{
25 Q_OBJECT
26
27public:
28 explicit ResourceSynchronizationJobPrivate(ResourceSynchronizationJob *parent)
29 : q(parent)
30 {
31 connect(&safetyTimer, &QTimer::timeout, this, &ResourceSynchronizationJobPrivate::slotTimeout);
32 safetyTimer.setInterval(std::chrono::seconds{30});
33 safetyTimer.setSingleShot(true);
34 }
35
36 void doStart() override;
37
38 ResourceSynchronizationJob *const q;
39 AgentInstance instance;
40 std::unique_ptr<org::freedesktop::Akonadi::Resource> interface;
41 QTimer safetyTimer;
42 int timeoutCount = 60;
43 bool collectionTreeOnly = false;
44 int timeoutCountLimit = 0;
45
46 void slotSynchronized();
47 void slotTimeout();
48};
49
51 : KJob(parent)
52 , d(new ResourceSynchronizationJobPrivate(this))
53{
54 d->instance = instance;
55}
56
58
59void ResourceSynchronizationJob::start()
60{
61 d->start();
62}
63
64void ResourceSynchronizationJob::setTimeoutCountLimit(int count)
65{
66 d->timeoutCountLimit = count;
67}
68
69int ResourceSynchronizationJob::timeoutCountLimit() const
70{
71 return d->timeoutCountLimit;
72}
73
75{
76 return d->collectionTreeOnly;
77}
78
80{
81 d->collectionTreeOnly = b;
82}
83
84void ResourceSynchronizationJobPrivate::doStart()
85{
86 if (!instance.isValid()) {
87 q->setError(KJob::UserDefinedError);
88 q->setErrorText(i18n("Invalid resource instance."));
89 q->emitResult();
90 return;
91 }
92
93 using ResourceIface = org::freedesktop::Akonadi::Resource;
94 interface = std::make_unique<ResourceIface>(ServerManager::agentServiceName(ServerManager::Resource, instance.identifier()),
95 QStringLiteral("/"),
97 if (collectionTreeOnly) {
98 connect(interface.get(), &ResourceIface::collectionTreeSynchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
99 } else {
100 connect(interface.get(), &ResourceIface::synchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
101 }
102
103 if (interface->isValid()) {
104 if (collectionTreeOnly) {
105 instance.synchronizeCollectionTree();
106 } else {
107 instance.synchronize();
108 }
109
110 safetyTimer.start();
111 } else {
112 q->setError(KJob::UserDefinedError);
113 q->setErrorText(i18n("Unable to obtain D-Bus interface for resource '%1'", instance.identifier()));
114 q->emitResult();
115 return;
116 }
117}
118
119void ResourceSynchronizationJobPrivate::slotSynchronized()
120{
121 using ResourceIface = org::freedesktop::Akonadi::Resource;
122 if (collectionTreeOnly) {
123 disconnect(interface.get(), &ResourceIface::collectionTreeSynchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
124 } else {
125 disconnect(interface.get(), &ResourceIface::synchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
126 }
127 safetyTimer.stop();
128 q->emitResult();
129}
130
131void ResourceSynchronizationJobPrivate::slotTimeout()
132{
133 instance = AgentManager::self()->instance(instance.identifier());
134 timeoutCount++;
135
136 if (timeoutCount > timeoutCountLimit) {
137 safetyTimer.stop();
138 q->setError(KJob::UserDefinedError);
139 q->setErrorText(i18n("Resource synchronization timed out."));
140 q->emitResult();
141 return;
142 }
143
144 if (instance.status() == AgentInstance::Idle) {
145 // try again, we might have lost the synchronized()/synchronizedCollectionTree() signal
146 qCDebug(AKONADICORE_LOG) << "trying again to sync resource" << instance.identifier();
147 if (collectionTreeOnly) {
148 instance.synchronizeCollectionTree();
149 } else {
150 instance.synchronize();
151 }
152 }
153}
154
156{
157 return d->instance;
158}
159
160} // namespace Akonadi
161
162#include "resourcesynchronizationjob.moc"
163
164#include "moc_resourcesynchronizationjob.cpp"
A representation of an agent instance.
bool isValid() const
Returns whether the agent instance object is valid.
@ 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...
bool collectionTreeOnly() const
Returns whether a full synchronization will be done, or just the collection tree (without items).
ResourceSynchronizationJob(const AgentInstance &instance, QObject *parent=nullptr)
Creates a new synchronization job for the given resource.
AgentInstance resource() const
Returns the resource that has been synchronized.
~ResourceSynchronizationJob() override
Destroys the synchronization job.
void setCollectionTreeOnly(bool collectionTreeOnly)
Sets the collectionTreeOnly property.
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.
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.