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 <QDBusConnection>
9 #include "kjobprivatebase_p.h"
10 #include "servermanager.h"
11 #include "agentinstance.h"
12 #include "agentmanager.h"
13 #include "akonadicore_debug.h"
14 #include "resourceinterface.h"
15 
16 #include <KLocalizedString>
17 
18 #include <QDBusInterface>
19 #include <QTimer>
20 
21 namespace Akonadi
22 {
23 
24 class ResourceSynchronizationJobPrivate : public KJobPrivateBase
25 {
26  Q_OBJECT
27 
28 public:
29  explicit ResourceSynchronizationJobPrivate(ResourceSynchronizationJob *parent)
30  : q(parent)
31  {
32  connect(&safetyTimer, &QTimer::timeout, this, &ResourceSynchronizationJobPrivate::slotTimeout);
33  safetyTimer.setInterval(std::chrono::seconds{30});
34  safetyTimer.setSingleShot(true);
35  }
36 
37  void doStart() override;
38 
39  ResourceSynchronizationJob *q;
40  AgentInstance instance;
41  std::unique_ptr<org::freedesktop::Akonadi::Resource> interface;
42  QTimer safetyTimer;
43  int timeoutCount = 60;
44  bool collectionTreeOnly = false;
45  int timeoutCountLimit = 0;
46 
47  void slotSynchronized();
48  void slotTimeout();
49 };
50 
52  : KJob(parent)
53  , d(new ResourceSynchronizationJobPrivate(this))
54 {
55  d->instance = instance;
56 }
57 
59 {
60  delete d;
61 }
62 
63 void ResourceSynchronizationJob::start()
64 {
65  d->start();
66 }
67 
68 void ResourceSynchronizationJob::setTimeoutCountLimit(int count)
69 {
70  d->timeoutCountLimit = count;
71 }
72 
73 int ResourceSynchronizationJob::timeoutCountLimit() const
74 {
75  return d->timeoutCountLimit;
76 }
77 
79 {
80  return d->collectionTreeOnly;
81 }
82 
84 {
85  d->collectionTreeOnly = b;
86 }
87 
88 void ResourceSynchronizationJobPrivate::doStart()
89 {
90  if (!instance.isValid()) {
91  q->setError(KJob::UserDefinedError);
92  q->setErrorText(i18n("Invalid resource instance."));
93  q->emitResult();
94  return;
95  }
96 
97  using ResourceIface = org::freedesktop::Akonadi::Resource;
98  interface = std::make_unique<ResourceIface>(
99  ServerManager::agentServiceName(ServerManager::Resource, instance.identifier()),
100  QStringLiteral("/"),
102  if (collectionTreeOnly) {
103  connect(interface.get(), &ResourceIface::collectionTreeSynchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
104  } else {
105  connect(interface.get(), &ResourceIface::synchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
106  }
107 
108  if (interface->isValid()) {
109  if (collectionTreeOnly) {
110  instance.synchronizeCollectionTree();
111  } else {
112  instance.synchronize();
113  }
114 
115  safetyTimer.start();
116  } else {
117  q->setError(KJob::UserDefinedError);
118  q->setErrorText(i18n("Unable to obtain D-Bus interface for resource '%1'", instance.identifier()));
119  q->emitResult();
120  return;
121  }
122 }
123 
124 void ResourceSynchronizationJobPrivate::slotSynchronized()
125 {
126  using ResourceIface = org::freedesktop::Akonadi::Resource;
127  if (collectionTreeOnly) {
128  disconnect(interface.get(), &ResourceIface::collectionTreeSynchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
129  } else {
130  disconnect(interface.get(), &ResourceIface::synchronized, this, &ResourceSynchronizationJobPrivate::slotSynchronized);
131  }
132  safetyTimer.stop();
133  q->emitResult();
134 }
135 
136 void ResourceSynchronizationJobPrivate::slotTimeout()
137 {
138  instance = AgentManager::self()->instance(instance.identifier());
139  timeoutCount++;
140 
141  if (timeoutCount > timeoutCountLimit) {
142  safetyTimer.stop();
143  q->setError(KJob::UserDefinedError);
144  q->setErrorText(i18n("Resource synchronization timed out."));
145  q->emitResult();
146  return;
147  }
148 
149  if (instance.status() == AgentInstance::Idle) {
150  // try again, we might have lost the synchronized()/synchronizedCollectionTree() signal
151  qCDebug(AKONADICORE_LOG) << "trying again to sync resource" << instance.identifier();
152  if (collectionTreeOnly) {
153  instance.synchronizeCollectionTree();
154  } else {
155  instance.synchronize();
156  }
157  }
158 }
159 
161 {
162  return d->instance;
163 }
164 
165 } // namespace Akonadi
166 
167 #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-2020 The KDE developers.
Generated on Wed Aug 12 2020 23:16:11 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.