Akonadi

resourcesynchronizationjob.cpp
1 /*
2  * SPDX-FileCopyrightText: 2009 Volker Krause <[email protected]>
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 
21 namespace Akonadi
22 {
23 class ResourceSynchronizationJobPrivate : public KJobPrivateBase
24 {
25  Q_OBJECT
26 
27 public:
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 {
59  delete d;
60 }
61 
62 void ResourceSynchronizationJob::start()
63 {
64  d->start();
65 }
66 
67 void ResourceSynchronizationJob::setTimeoutCountLimit(int count)
68 {
69  d->timeoutCountLimit = count;
70 }
71 
72 int ResourceSynchronizationJob::timeoutCountLimit() const
73 {
74  return d->timeoutCountLimit;
75 }
76 
78 {
79  return d->collectionTreeOnly;
80 }
81 
83 {
84  d->collectionTreeOnly = b;
85 }
86 
87 void ResourceSynchronizationJobPrivate::doStart()
88 {
89  if (!instance.isValid()) {
90  q->setError(KJob::UserDefinedError);
91  q->setErrorText(i18n("Invalid resource instance."));
92  q->emitResult();
93  return;
94  }
95 
96  using ResourceIface = org::freedesktop::Akonadi::Resource;
97  interface = std::make_unique<ResourceIface>(ServerManager::agentServiceName(ServerManager::Resource, instance.identifier()),
98  QStringLiteral("/"),
100  if (collectionTreeOnly) {
101  connect(interface.get(), &ResourceIface::collectionTreeSynchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
102  } else {
103  connect(interface.get(), &ResourceIface::synchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
104  }
105 
106  if (interface->isValid()) {
107  if (collectionTreeOnly) {
108  instance.synchronizeCollectionTree();
109  } else {
110  instance.synchronize();
111  }
112 
113  safetyTimer.start();
114  } else {
115  q->setError(KJob::UserDefinedError);
116  q->setErrorText(i18n("Unable to obtain D-Bus interface for resource '%1'", instance.identifier()));
117  q->emitResult();
118  return;
119  }
120 }
121 
122 void ResourceSynchronizationJobPrivate::slotSynchronized()
123 {
124  using ResourceIface = org::freedesktop::Akonadi::Resource;
125  if (collectionTreeOnly) {
126  disconnect(interface.get(), &ResourceIface::collectionTreeSynchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
127  } else {
128  disconnect(interface.get(), &ResourceIface::synchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
129  }
130  safetyTimer.stop();
131  q->emitResult();
132 }
133 
134 void ResourceSynchronizationJobPrivate::slotTimeout()
135 {
136  instance = AgentManager::self()->instance(instance.identifier());
137  timeoutCount++;
138 
139  if (timeoutCount > timeoutCountLimit) {
140  safetyTimer.stop();
141  q->setError(KJob::UserDefinedError);
142  q->setErrorText(i18n("Resource synchronization timed out."));
143  q->emitResult();
144  return;
145  }
146 
147  if (instance.status() == AgentInstance::Idle) {
148  // try again, we might have lost the synchronized()/synchronizedCollectionTree() signal
149  qCDebug(AKONADICORE_LOG) << "trying again to sync resource" << instance.identifier();
150  if (collectionTreeOnly) {
151  instance.synchronizeCollectionTree();
152  } else {
153  instance.synchronize();
154  }
155  }
156 }
157 
159 {
160  return d->instance;
161 }
162 
163 } // namespace Akonadi
164 
165 #include "resourcesynchronizationjob.moc"
The agent instance does currently nothing.
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.
QString identifier() const
Returns the unique identifier of the agent instance.
QDBusConnection sessionBus()
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
~ResourceSynchronizationJob() override
Destroys the synchronization job.
Represents one agent instance and takes care of communication with it.
void timeout()
AgentInstance instance(const QString &identifier) const
Returns the agent instance with the given identifier or an invalid agent instance if the identifier d...
AgentInstance resource() const
Returns the resource that has been synchronized.
QString i18n(const char *text, const TYPE &arg...)
if(recurs()&&!first)
Helper integration between Akonadi and Qt.
static AgentManager * self()
Returns the global instance of the agent manager.
A representation of an agent instance.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setCollectionTreeOnly(bool collectionTreeOnly)
Sets the collectionTreeOnly property.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Jun 22 2021 23:16:52 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.