Merge lp:~renatofilho/address-book-service/abort-in-case-of-eds-fail-to-start into lp:address-book-service

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Bill Filler
Approved revision: 161
Merged at revision: 140
Proposed branch: lp:~renatofilho/address-book-service/abort-in-case-of-eds-fail-to-start
Merge into: lp:address-book-service
Diff against target: 729 lines (+190/-101)
15 files modified
CMakeLists.txt (+1/-0)
contacts/CMakeLists.txt (+1/-1)
contacts/contacts-service.cpp (+14/-36)
contacts/contacts-service.h (+0/-3)
contacts/qcontact-engineid.cpp (+12/-0)
contacts/qcontactrequest-data.cpp (+0/-1)
debian/address-book-service.install (+1/-1)
lib/addressbook-adaptor.cpp (+1/-1)
lib/addressbook-adaptor.h (+3/-4)
lib/addressbook.cpp (+126/-45)
lib/addressbook.h (+16/-4)
lib/view.cpp (+8/-2)
src/main.cpp (+1/-1)
upstart/CMakeLists.txt (+5/-0)
upstart/address-book-service.conf.in (+1/-2)
To merge this branch: bzr merge lp:~renatofilho/address-book-service/abort-in-case-of-eds-fail-to-start
Reviewer Review Type Date Requested Status
Bill Filler (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+235510@code.launchpad.net

Commit message

Correct release folks if eds die.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:140
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~renatofilho/address-book-service/abort-in-case-of-eds-fail-to-start/+merge/235510/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/address-book-service-ci/290/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-service-utopic-armhf-ci/62
        deb: http://jenkins.qa.ubuntu.com/job/address-book-service-utopic-armhf-ci/62/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-service-utopic-i386-ci/62
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/5069/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/3700
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/4818/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/6321
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/6321/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/13560
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/3092
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/4009
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/4009/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-service-ci/290/rebuild

review: Needs Fixing (continuous-integration)
141. By Renato Araujo Oliveira Filho

Remove unused variables and clear request list during the shutdown.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Bill Filler (bfiller) wrote :

Doesn't work:
1) service does not correctly try to restart EDS 10 times, it locks up. You can test by moving the evolution-addressbook-factory to a different name and restarting

review: Needs Fixing
Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

Works as expected for me.

As you can see in the log bellow, the service try to restart eds 10 times it all fails it finish itself.

The problem of removing the factory will cause the server to enter in a infinity loop, since after the first 10 tries it will exit but upstart will start it again and it will try restart eds 10 times again.

Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :
Download full text (11.7 KiB)

START Ter Set 23 14:35:45 BRT 2014
Initialize folks
Service started

(process:5976): folks-WARNING **: Error preparing persona store 'eds:<email address hidden>': Couldn't open address book ‘<email address hidden>’: Unable to connect to '<email address hidden>': Error calling StartServiceByName for org.gnome.evolution.dataserver.AddressBook6: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ExecFailed: Failed to execute program /usr/lib/evolution/evolution-addressbook-factory: Success
QDateTime("2014-09-23 14:35:45.936 BRT Qt::LocalTime") EDS did not start, trying to reload folks;

(process:5976): folks-WARNING **: Error preparing persona store 'eds:system-address-book': Couldn't open address book ‘system-address-book’: Unable to connect to 'Pessoal': Error calling StartServiceByName for org.gnome.evolution.dataserver.AddressBook6: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ExecFailed: Failed to execute program /usr/lib/evolution/evolution-addressbook-factory: Success
Trying to reload folks
Unprepare folks

(process:5976): GLib-GObject-CRITICAL **: g_signal_handler_disconnect: assertion 'handler_id > 0' failed
Initialize folks

(process:5976): folks-WARNING **: Error preparing persona store 'eds:<email address hidden>': Couldn't open address book ‘<email address hidden>’: Unable to connect to '<email address hidden>': Error calling StartServiceByName for org.gnome.evolution.dataserver.AddressBook6: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ExecFailed: Failed to execute program /usr/lib/evolution/evolution-addressbook-factory: Success
QDateTime("2014-09-23 14:35:46.630 BRT Qt::LocalTime") EDS did not start, trying to reload folks;

(process:5976): folks-WARNING **: Error preparing persona store 'eds:system-address-book': Couldn't open address book ‘system-address-book’: Unable to connect to 'Pessoal': Error calling StartServiceByName for org.gnome.evolution.dataserver.AddressBook6: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ExecFailed: Failed to execute program /usr/lib/evolution/evolution-addressbook-factory: Success
Trying to reload folks
Unprepare folks

(process:5976): GLib-GObject-CRITICAL **: g_signal_handler_disconnect: assertion 'handler_id > 0' failed
Initialize folks

(process:5976): folks-WARNING **: Error preparing persona store 'eds:<email address hidden>': Couldn't open address book ‘<email address hidden>’: Unable to connect to '<email address hidden>': Error calling StartServiceByName for org.gnome.evolution.dataserver.AddressBook6: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ExecFailed: Failed to execute program /usr/lib/evolution/evolution-addressbook-factory: Success
QDateTime("2014-09-23 14:35:47.827 BRT Qt::LocalTime") EDS did not start, trying to reload folks;

(process:5976): folks-WARNING **: Error preparing persona store 'eds:system-address-book': Couldn't open address book ‘system-address-book’: Unable to connect to 'Pessoal': Error calling StartServiceByName for org.gnome.evolution.dataserver.AddressBook6: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ExecFailed: Failed to execute program /usr/lib/evolution/evolution-addressbook-factory: Success
Trying to reload folks
Unprepare folks

(process:5976): GLib-GObject-CRITICAL **: g_signal_handler_disconnect: ass...

142. By Renato Araujo Oliveira Filho

Fixed typo.
Added warning messaging if the service fail to start eds.

143. By Renato Araujo Oliveira Filho

Updated upstart service file to be platform independent.

144. By Renato Araujo Oliveira Filho

Added debug messages while the service apper or disapper on QtContacts.

145. By Renato Araujo Oliveira Filho

Added a timeout while unpreparing folks.

146. By Renato Araujo Oliveira Filho

Track service changes.

Contact service now export "uuid" property that changes every time that the contacts data change.
QContact plugin will disconnect from dbus while the application is not active and will use the "uuid" service property to track service change while returning from the suspend mode.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
147. By Renato Araujo Oliveira Filho

Add missing file.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
148. By Renato Araujo Oliveira Filho

Fixed upstart file with the correct service path.
Added more debug.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Bill Filler (bfiller) wrote :

Can you split this into two MR's please. One that only has the changes related to restarting the service. And the other for the new connection detection.

review: Needs Fixing
149. By Renato Araujo Oliveira Filho

Reverted QtContacts resume ans suspend implementation.

150. By Renato Araujo Oliveira Filho

Revert changes.

151. By Renato Araujo Oliveira Filho

Cancel all pending requests if the service reload.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
152. By Renato Araujo Oliveira Filho

Fixed service deinitialize.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
153. By Renato Araujo Oliveira Filho

Added timestamp on debug message.

154. By Renato Araujo Oliveira Filho

force application exit if the eds did not start.

155. By Renato Araujo Oliveira Filho

Added more debug.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
156. By Renato Araujo Oliveira Filho

Correct unprepare folks.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
157. By Renato Araujo Oliveira Filho

Reduce the maxRetry back 10.
Increase the idle time before each retry.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
158. By Renato Araujo Oliveira Filho

Force folks to reload eds during folks restart.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
159. By Renato Araujo Oliveira Filho

Fixed contact reload when service restart.

160. By Renato Araujo Oliveira Filho

Fixed server to works without EDS.

161. By Renato Araujo Oliveira Filho

Avoid overflow.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Bill Filler (bfiller) wrote :

finally all working :)
Did you perform an exploratory manual test run of the code change and any related functionality on device or emulator?
yes

Did you successfully run all tests found in your component's Test Plan (https://wiki.ubuntu.com/Process/Merges/TestPlan/<package-name>) on device or emulator?
yes

Did CI run pass? If not, please explain why.
yes

Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?
yes

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-08-12 15:38:08 +0000
3+++ CMakeLists.txt 2014-09-30 16:43:01 +0000
4@@ -63,6 +63,7 @@
5 add_subdirectory(lib)
6 add_subdirectory(src)
7 add_subdirectory(contacts)
8+add_subdirectory(upstart)
9 if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc")
10 # Some tests fail when running on PPPC check bug #1294229
11 message(STATUS "Tests disable for ppc")
12
13=== modified file 'contacts/CMakeLists.txt'
14--- contacts/CMakeLists.txt 2014-03-19 12:21:35 +0000
15+++ contacts/CMakeLists.txt 2014-09-30 16:43:01 +0000
16@@ -4,7 +4,7 @@
17
18 set(QCONTACTS_BACKEND_SRCS
19 qcontact-backend.cpp
20- qcontact-engineid.cpp
21+ qcontact-engineid.cpp
22 qcontactfetchrequest-data.cpp
23 qcontactfetchbyidrequest-data.cpp
24 qcontactremoverequest-data.cpp
25
26=== modified file 'contacts/contacts-service.cpp'
27--- contacts/contacts-service.cpp 2014-09-05 20:58:28 +0000
28+++ contacts/contacts-service.cpp 2014-09-30 16:43:01 +0000
29@@ -101,8 +101,7 @@
30 namespace galera
31 {
32 GaleraContactsService::GaleraContactsService(const QString &managerUri)
33- : m_selfContactId(),
34- m_managerUri(managerUri),
35+ : m_managerUri(managerUri),
36 m_serviceIsReady(false),
37 m_iface(0)
38 {
39@@ -131,23 +130,14 @@
40 }
41
42 GaleraContactsService::GaleraContactsService(const GaleraContactsService &other)
43- : m_selfContactId(other.m_selfContactId),
44- m_managerUri(other.m_managerUri),
45+ : m_managerUri(other.m_managerUri),
46 m_iface(other.m_iface)
47 {
48 }
49
50 GaleraContactsService::~GaleraContactsService()
51 {
52- while(!m_pendingRequests.isEmpty()) {
53- QPointer<QContactAbstractRequest> request = m_pendingRequests.takeFirst();
54- if (request) {
55- request->cancel();
56- request->waitForFinished();
57- }
58- }
59 m_runningRequests.clear();
60-
61 delete m_serviceWatcher;
62 }
63
64@@ -157,9 +147,11 @@
65 if (name == m_serviceName) {
66 if (!newOwner.isEmpty()) {
67 // service appear
68+ qDebug() << "Service appeared";
69 initialize();
70 } else if (!m_iface.isNull()) {
71 // lost service
72+ qDebug() << "Service disappeared";
73 deinitialize();
74 }
75 }
76@@ -167,13 +159,8 @@
77
78 void GaleraContactsService::onServiceReady()
79 {
80- m_serviceIsReady = true;
81- while(!m_pendingRequests.isEmpty()) {
82- QPointer<QContactAbstractRequest> request = m_pendingRequests.takeFirst();
83- if (request) {
84- addRequest(request);
85- }
86- }
87+ m_serviceIsReady = m_iface.data()->property("isReady").toBool();
88+ Q_EMIT serviceChanged();
89 }
90
91 void GaleraContactsService::initialize()
92@@ -184,12 +171,10 @@
93 CPIM_ADDRESSBOOK_IFACE_NAME));
94 if (!m_iface->lastError().isValid()) {
95 m_serviceIsReady = m_iface.data()->property("isReady").toBool();
96- connect(m_iface.data(), SIGNAL(ready()), this, SLOT(onServiceReady()));
97- connect(m_iface.data(), SIGNAL(reloaded()), this, SIGNAL(serviceChanged()));
98+ connect(m_iface.data(), SIGNAL(readyChanged()), this, SLOT(onServiceReady()));
99 connect(m_iface.data(), SIGNAL(contactsAdded(QStringList)), this, SLOT(onContactsAdded(QStringList)));
100 connect(m_iface.data(), SIGNAL(contactsRemoved(QStringList)), this, SLOT(onContactsRemoved(QStringList)));
101 connect(m_iface.data(), SIGNAL(contactsUpdated(QStringList)), this, SLOT(onContactsUpdated(QStringList)));
102-
103 Q_EMIT serviceChanged();
104 } else {
105 qWarning() << "Fail to connect with service:" << m_iface->lastError();
106@@ -200,19 +185,14 @@
107
108 void GaleraContactsService::deinitialize()
109 {
110- Q_FOREACH(QContactRequestData* rData, m_runningRequests) {
111- rData->cancel();
112- rData->request()->waitForFinished();
113- rData->finish(QContactManager::UnspecifiedError);
114- }
115-
116- if (!m_iface.isNull()) {
117- m_id.clear();
118- Q_EMIT serviceChanged();
119+ // wait until all request finish
120+ while (m_runningRequests.size()) {
121+ QCoreApplication::processEvents();
122 }
123
124 // this will make the service re-initialize
125 m_iface->call("ping");
126+
127 if (m_iface->lastError().isValid()) {
128 qWarning() << m_iface->lastError();
129 m_iface.clear();
130@@ -220,6 +200,8 @@
131 } else {
132 m_serviceIsReady = m_iface.data()->property("isReady").toBool();
133 }
134+
135+ Q_EMIT serviceChanged();
136 }
137
138 bool GaleraContactsService::isOnline() const
139@@ -282,6 +264,7 @@
140 m_runningRequests << data;
141
142 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, 0);
143+ data->updateWatcher(watcher);
144 QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
145 [=](QDBusPendingCallWatcher *call) {
146 this->fetchContactsGroupsContinue(data, call);
147@@ -765,11 +748,6 @@
148 return;
149 }
150
151- if (!m_serviceIsReady) {
152- m_pendingRequests << QPointer<QtContacts::QContactAbstractRequest>(request);
153- return;
154- }
155-
156 Q_ASSERT(request->state() == QContactAbstractRequest::ActiveState);
157 switch (request->type()) {
158 case QContactAbstractRequest::ContactFetchRequest:
159
160=== modified file 'contacts/contacts-service.h'
161--- contacts/contacts-service.h 2014-05-27 14:41:55 +0000
162+++ contacts/contacts-service.h 2014-09-30 16:43:01 +0000
163@@ -79,8 +79,6 @@
164 void onVCardsParsed(QList<QtContacts::QContact> contacts);
165
166 private:
167- QString m_id;
168- QtContacts::QContactId m_selfContactId; // the "MyCard" contact id
169 QString m_managerUri; // for faster lookup.
170 QDBusServiceWatcher *m_serviceWatcher;
171 bool m_serviceIsReady;
172@@ -89,7 +87,6 @@
173 QSharedPointer<QDBusInterface> m_iface;
174 QString m_serviceName;
175 QSet<QContactRequestData*> m_runningRequests;
176- QQueue<QPointer<QtContacts::QContactAbstractRequest> > m_pendingRequests;
177
178 Q_INVOKABLE void initialize();
179 Q_INVOKABLE void deinitialize();
180
181=== modified file 'contacts/qcontact-engineid.cpp'
182--- contacts/qcontact-engineid.cpp 2014-02-04 19:12:46 +0000
183+++ contacts/qcontact-engineid.cpp 2014-09-30 16:43:01 +0000
184@@ -54,6 +54,12 @@
185
186 bool GaleraEngineId::isEqualTo(const QtContacts::QContactEngineId *other) const
187 {
188+ Q_ASSERT(other);
189+ if (!other) {
190+ qWarning() << "GaleraEngineId::isEqualTo, other is null";
191+ return false;
192+ }
193+
194 if (m_contactId != static_cast<const GaleraEngineId*>(other)->m_contactId)
195 return false;
196 return true;
197@@ -61,6 +67,12 @@
198
199 bool GaleraEngineId::isLessThan(const QtContacts::QContactEngineId *other) const
200 {
201+ Q_ASSERT(other);
202+ if (!other) {
203+ qWarning() << "GaleraEngineId::isLessThan, other is null";
204+ return false;
205+ }
206+
207 const GaleraEngineId *otherPtr = static_cast<const GaleraEngineId*>(other);
208 if (m_managerUri < otherPtr->m_managerUri)
209 return true;
210
211=== modified file 'contacts/qcontactrequest-data.cpp'
212--- contacts/qcontactrequest-data.cpp 2014-07-01 14:43:55 +0000
213+++ contacts/qcontactrequest-data.cpp 2014-09-30 16:43:01 +0000
214@@ -61,7 +61,6 @@
215 if (m_eventLoop) {
216 m_eventLoop->quit();
217 }
218-
219 }
220
221 void QContactRequestData::wait()
222
223=== modified file 'debian/address-book-service.install'
224--- debian/address-book-service.install 2014-08-12 15:38:08 +0000
225+++ debian/address-book-service.install 2014-09-30 16:43:01 +0000
226@@ -1,2 +1,2 @@
227 usr/lib/*/address-book-service/address-book-service
228-upstart/address-book-service.conf /usr/share/upstart/sessions
229+usr/share/upstart/sessions/address-book-service.conf
230
231=== modified file 'lib/addressbook-adaptor.cpp'
232--- lib/addressbook-adaptor.cpp 2014-04-09 19:45:40 +0000
233+++ lib/addressbook-adaptor.cpp 2014-09-30 16:43:01 +0000
234@@ -29,7 +29,7 @@
235 m_connection(connection)
236 {
237 setAutoRelaySignals(true);
238- connect(m_addressBook, SIGNAL(ready()), SIGNAL(ready()));
239+ connect(m_addressBook, SIGNAL(readyChanged()), SIGNAL(readyChanged()));
240 }
241
242 AddressBookAdaptor::~AddressBookAdaptor()
243
244=== modified file 'lib/addressbook-adaptor.h'
245--- lib/addressbook-adaptor.h 2014-09-05 20:58:28 +0000
246+++ lib/addressbook-adaptor.h 2014-09-30 16:43:01 +0000
247@@ -50,8 +50,7 @@
248 " <signal name=\"asyncOperationResult\">\n"
249 " <arg direction=\"out\" type=\"a(ss)\" name=\"errorMap\"/>\n"
250 " </signal>\n"
251-" <signal name=\"ready\"/>\n"
252-" <signal name=\"reloaded\"/>\n"
253+" <signal name=\"readyChanged\"/>\n"
254 " <method name=\"ping\">\n"
255 " <arg direction=\"out\" type=\"b\"/>\n"
256 " </method>\n"
257@@ -106,7 +105,7 @@
258 " </method>\n"
259 " </interface>\n"
260 "")
261- Q_PROPERTY(bool isReady READ isReady NOTIFY ready)
262+ Q_PROPERTY(bool isReady READ isReady NOTIFY readyChanged)
263 public:
264 AddressBookAdaptor(const QDBusConnection &connection, AddressBook *parent);
265 virtual ~AddressBookAdaptor();
266@@ -131,7 +130,7 @@
267 void contactsRemoved(const QStringList &ids);
268 void contactsUpdated(const QStringList &ids);
269 void asyncOperationResult(QMap<QString, QString> errors);
270- void ready();
271+ void readyChanged();
272 void reloaded();
273
274 private:
275
276=== modified file 'lib/addressbook.cpp'
277--- lib/addressbook.cpp 2014-09-10 13:02:56 +0000
278+++ lib/addressbook.cpp 2014-09-30 16:43:01 +0000
279@@ -96,6 +96,8 @@
280 m_notifyContactUpdate(0),
281 m_edsIsLive(false),
282 m_ready(false),
283+ m_isAboutToQuit(false),
284+ m_isAboutToReload(false),
285 m_individualsChangedDetailedId(0),
286 m_notifyIsQuiescentHandlerId(0),
287 m_connection(QDBusConnection::sessionBus())
288@@ -112,8 +114,14 @@
289
290 AddressBook::~AddressBook()
291 {
292- shutdown();
293- // destructor
294+ if (m_individualAggregator) {
295+ qWarning() << "Addressbook destructor called while running, you should call shutdown first";
296+ shutdown();
297+ while (m_adaptor) {
298+ QCoreApplication::processEvents();
299+ }
300+ }
301+
302 if (m_notifyContactUpdate) {
303 delete m_notifyContactUpdate;
304 m_notifyContactUpdate = 0;
305@@ -176,13 +184,7 @@
306 // flusing any pending notification
307 m_notifyContactUpdate->flush();
308
309- // notify about contacts removal
310- if (m_contacts) {
311- m_notifyContactUpdate->insertRemovedContacts(m_contacts->keys().toSet());
312- m_notifyContactUpdate->flush();
313- }
314-
315- m_ready = false;
316+ setIsReady(false);
317
318 Q_FOREACH(View* view, m_views) {
319 view->close();
320@@ -194,20 +196,31 @@
321 m_contacts = 0;
322 }
323
324+ qDebug() << "Will destroy aggregator" << (void*) m_individualAggregator;
325 if (m_individualAggregator) {
326 g_signal_handler_disconnect(m_individualAggregator,
327 m_individualsChangedDetailedId);
328 g_signal_handler_disconnect(m_individualAggregator,
329 m_notifyIsQuiescentHandlerId);
330 m_individualsChangedDetailedId = m_notifyIsQuiescentHandlerId = 0;
331- g_clear_object(&m_individualAggregator);
332+
333+ // make it sync
334+ qDebug() << "call unprepare";
335+ folks_individual_aggregator_unprepare(m_individualAggregator,
336+ AddressBook::folksUnprepared,
337+ this);
338 }
339 }
340
341 void AddressBook::shutdown()
342 {
343+ m_isAboutToQuit = true;
344 unprepareFolks();
345+}
346
347+void AddressBook::continueShutdown()
348+{
349+ qDebug() << "Folks is not running anymore";
350 if (m_adaptor) {
351 if (m_connection.interface() &&
352 m_connection.interface()->isValid()) {
353@@ -224,14 +237,23 @@
354 }
355 }
356
357+void AddressBook::setIsReady(bool isReady)
358+{
359+ if (isReady != m_ready) {
360+ m_ready = isReady;
361+ if (m_adaptor) {
362+ Q_EMIT readyChanged();
363+ }
364+ }
365+}
366+
367 void AddressBook::prepareFolks()
368 {
369+ qDebug() << "Initialize folks";
370 m_contacts = new ContactsMap;
371 m_individualAggregator = folks_individual_aggregator_dup();
372- g_object_get(G_OBJECT(m_individualAggregator), "is-quiescent", &m_ready, NULL);
373- if (m_ready) {
374- AddressBook::isQuiescentChanged(G_OBJECT(m_individualAggregator), NULL, this);
375- }
376+ gboolean ready;
377+ g_object_get(G_OBJECT(m_individualAggregator), "is-quiescent", &ready, NULL);
378 m_notifyIsQuiescentHandlerId = g_signal_connect(m_individualAggregator,
379 "notify::is-quiescent",
380 (GCallback) AddressBook::isQuiescentChanged,
381@@ -245,6 +267,25 @@
382 folks_individual_aggregator_prepare(m_individualAggregator,
383 (GAsyncReadyCallback) AddressBook::prepareFolksDone,
384 this);
385+ if (ready) {
386+ qDebug() << "Folks is already in quiescent mode";
387+ setIsReady(ready);
388+ }
389+}
390+
391+void AddressBook::unprepareEds()
392+{
393+ FolksBackendStore *store = folks_backend_store_dup();
394+ FolksBackend *edsBackend = folks_backend_store_dup_backend_by_name(store, "eds");
395+ if (edsBackend && folks_backend_get_is_prepared(edsBackend)) {
396+ qDebug() << "WILL unprepare EDS";
397+ folks_backend_unprepare(edsBackend,
398+ AddressBook::edsUnprepared,
399+ this);
400+ } else {
401+ qDebug() << "Eds not prepared will restart folks";
402+ prepareFolks();
403+ }
404 }
405
406 void AddressBook::connectWithEDS()
407@@ -257,6 +298,7 @@
408 if (qEnvironmentVariableIsSet("FOLKS_BACKENDS_ALLOWED")) {
409 QString allowedBackends = qgetenv("FOLKS_BACKENDS_ALLOWED");
410 if (!allowedBackends.contains("eds")) {
411+ m_edsIsLive = true;
412 return;
413 }
414 }
415@@ -278,7 +320,7 @@
416
417
418 // WORKAROUND: Will ceck for EDS after the service get ready
419- connect(this, SIGNAL(ready()), SLOT(checkForEds()));
420+ connect(this, SIGNAL(readyChanged()), SLOT(checkForEds()));
421 }
422
423 SourceList AddressBook::availableSources(const QDBusMessage &message)
424@@ -307,7 +349,6 @@
425 personaStoreTypeId = QString::fromUtf8(folks_persona_store_get_type_id(store));
426 }
427 if (personaStoreTypeId == "dummy") {
428- qDebug() << "Create source on dummy" << sourceId;
429 FolksBackendStore *backendStore = folks_backend_store_dup();
430 FolksBackend *dummy = folks_backend_store_dup_backend_by_name(backendStore, "dummy");
431
432@@ -390,6 +431,53 @@
433 delete rData;
434 }
435
436+void AddressBook::folksUnprepared(GObject *source, GAsyncResult *res, void *data)
437+{
438+ AddressBook *self = static_cast<AddressBook*>(data);
439+ GError *error = NULL;
440+ folks_individual_aggregator_unprepare_finish(FOLKS_INDIVIDUAL_AGGREGATOR(source), res, &error);
441+ if (error) {
442+ qWarning() << "Fail to unprepare folks:" << error->message;
443+ g_error_free(error);
444+ }
445+ g_clear_object(&self->m_individualAggregator);
446+
447+ qDebug() << "Folks unprepared" << (void*) self->m_individualAggregator;
448+ if (self->m_isAboutToQuit) {
449+ self->continueShutdown();
450+ } else {
451+ self->unprepareEds();
452+ }
453+}
454+
455+void AddressBook::edsUnprepared(GObject *source, GAsyncResult *res, void *data)
456+{
457+ GError *error = NULL;
458+ folks_backend_unprepare_finish(FOLKS_BACKEND(source), res, &error);
459+ if (error) {
460+ qWarning() << "Fail to unprepare eds:" << error->message;
461+ g_error_free(error);
462+ }
463+ qDebug() << "EDS unprepared";
464+ folks_backend_prepare(FOLKS_BACKEND(source),
465+ AddressBook::edsPrepared,
466+ data);
467+}
468+
469+void AddressBook::edsPrepared(GObject *source, GAsyncResult *res, void *data)
470+{
471+ AddressBook *self = static_cast<AddressBook*>(data);
472+ GError *error = NULL;
473+ folks_backend_prepare_finish(FOLKS_BACKEND(source), res, &error);
474+ if (error) {
475+ qWarning() << "Fail to prepare eds:" << error->message;
476+ g_error_free(error);
477+ }
478+ // remove reference created by parent function
479+ g_object_unref(source);
480+ // will start folks again
481+ self->prepareFolks();
482+}
483
484 void AddressBook::createSourceDone(GObject *source,
485 GAsyncResult *res,
486@@ -637,12 +725,7 @@
487
488 View *AddressBook::query(const QString &clause, const QString &sort, const QStringList &sources)
489 {
490- // wait for the service be ready for queries
491- while(!m_ready) {
492- QCoreApplication::processEvents();
493- }
494-
495- View *view = new View(clause, sort, sources, m_contacts, this);
496+ View *view = new View(clause, sort, sources, m_ready ? m_contacts : 0, this);
497 m_views << view;
498 connect(view, SIGNAL(closed()), this, SLOT(viewClosed()));
499 return view;
500@@ -660,15 +743,11 @@
501
502 void AddressBook::onEdsServiceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
503 {
504- qDebug() << name << oldOwner << newOwner;
505 if (newOwner.isEmpty()) {
506 m_edsIsLive = false;
507+ m_isAboutToReload = true;
508 qWarning() << "EDS died: restarting service" << m_individualsChangedDetailedId;
509- // reset folks objects
510 unprepareFolks();
511- prepareFolks();
512-
513- Q_EMIT m_adaptor->reloaded();
514 } else {
515 m_edsIsLive = true;
516 }
517@@ -734,7 +813,7 @@
518
519 bool AddressBook::isReady() const
520 {
521- return m_ready;
522+ return m_ready && m_edsIsLive;
523 }
524
525 QStringList AddressBook::updateContacts(const QStringList &contacts, const QDBusMessage &message)
526@@ -754,7 +833,6 @@
527 void AddressBook::updateContactsDone(const QString &contactId,
528 const QString &error)
529 {
530- qDebug() << Q_FUNC_INFO;
531 int currentContactIndex = m_updateCommandResult.size() - m_updateCommandPendingContacts.size() - 1;
532
533 if (!error.isEmpty()) {
534@@ -937,12 +1015,11 @@
535
536 void AddressBook::isQuiescentChanged(GObject *source, GParamSpec *param, AddressBook *self)
537 {
538- Q_UNUSED(source);
539 Q_UNUSED(param);
540-
541- g_object_get(source, "is-quiescent", &self->m_ready, NULL);
542- if (self->m_ready && self->m_adaptor) {
543- Q_EMIT self->ready();
544+ gboolean ready = false;
545+ g_object_get(source, "is-quiescent", &ready, NULL);
546+ if (self) {
547+ self->setIsReady(ready);
548 }
549 }
550
551@@ -992,27 +1069,31 @@
552 // we will try to reload folks if this happen
553 void AddressBook::checkForEds()
554 {
555+ if (!m_ready) {
556+ return;
557+ }
558+
559 // Use maxRetry value to avoid infinite loop
560- static const int maxRerty = 10;
561+ static const int maxRetry = 10;
562 static int retryCount = 0;
563- if (retryCount >= maxRerty) {
564+
565+ qDebug() << "Check for EDS attempt number " << retryCount;
566+ if (retryCount >= maxRetry) {
567+ // abort when reach the maxRetry
568+ qWarning() << QDateTime::currentDateTime().toString() << "Fail to start EDS the service will abort";
569+ QTimer::singleShot(500, this, SLOT(shutdown()));
570 return;
571 }
572 retryCount++;
573
574 if (!m_edsIsLive) {
575- // wait some ms to restart folks, this ms increase 500ms for each retryCount
576- QTimer::singleShot(500 * retryCount, this, SLOT(reloadFolks()));
577- qWarning() << "EDS did not start, trying to reload folks;";
578+ // wait some ms to restart folks, this increase 1s for each retryCount
579+ m_isAboutToReload = true;
580+ QTimer::singleShot(1000 * retryCount, this, SLOT(unprepareFolks()));
581+ qWarning() << QDateTime::currentDateTime().toString() << "EDS did not start, trying to reload folks";
582 } else {
583 retryCount = 0;
584 }
585 }
586
587-void AddressBook::reloadFolks()
588-{
589- unprepareFolks();
590- prepareFolks();
591-}
592-
593 } //namespace
594
595=== modified file 'lib/addressbook.h'
596--- lib/addressbook.h 2014-09-10 13:02:56 +0000
597+++ lib/addressbook.h 2014-09-30 16:43:01 +0000
598@@ -63,7 +63,7 @@
599
600 Q_SIGNALS:
601 void stopped();
602- void ready();
603+ void readyChanged();
604
605 public Q_SLOTS:
606 bool start();
607@@ -87,7 +87,7 @@
608
609 // WORKAROUND: Check if EDS was running when the service started
610 void checkForEds();
611- void reloadFolks();
612+ void unprepareFolks();
613
614 private:
615 FolksIndividualAggregator *m_individualAggregator;
616@@ -100,6 +100,8 @@
617
618 bool m_edsIsLive;
619 bool m_ready;
620+ bool m_isAboutToQuit;
621+ bool m_isAboutToReload;
622 gulong m_individualsChangedDetailedId;
623 gulong m_notifyIsQuiescentHandlerId;
624 QDBusConnection m_connection;
625@@ -117,7 +119,6 @@
626 // dbus service name
627 QString m_serviceName;
628
629-
630 // Disable copy contructor
631 AddressBook(const AddressBook&);
632
633@@ -130,8 +131,10 @@
634 static void quitSignalHandler(int unused);
635
636 void prepareFolks();
637- void unprepareFolks();
638+ void unprepareEds();
639 void connectWithEDS();
640+ void continueShutdown();
641+ void setIsReady(bool isReady);
642 bool registerObject(QDBusConnection &connection);
643 QString removeContact(FolksIndividual *individual);
644 QString addContact(FolksIndividual *individual);
645@@ -166,6 +169,15 @@
646 static void removeSourceDone(GObject *source,
647 GAsyncResult *res,
648 void *data);
649+ static void folksUnprepared(GObject *source,
650+ GAsyncResult *res,
651+ void *data);
652+ static void edsUnprepared(GObject *source,
653+ GAsyncResult *res,
654+ void *data);
655+ static void edsPrepared(GObject *source,
656+ GAsyncResult *res,
657+ void *data);
658 friend class DirtyContactsNotify;
659 };
660
661
662=== modified file 'lib/view.cpp'
663--- lib/view.cpp 2014-06-11 22:18:53 +0000
664+++ lib/view.cpp 2014-09-30 16:43:01 +0000
665@@ -105,6 +105,10 @@
666 protected:
667 void run()
668 {
669+ if (!m_allContacts) {
670+ return;
671+ }
672+
673 m_allContacts->lock();
674
675 // only sort contacts if the contacts was stored in a different order into the contacts map
676@@ -164,8 +168,10 @@
677 m_filterThread(new FilterThread(clause, sort, allContacts)),
678 m_adaptor(0)
679 {
680- m_filterThread->start();
681- connect(m_filterThread, SIGNAL(finished()), SIGNAL(countChanged()));
682+ if (allContacts) {
683+ connect(m_filterThread, SIGNAL(finished()), SIGNAL(countChanged()));
684+ m_filterThread->start();
685+ }
686 }
687
688 View::~View()
689
690=== modified file 'src/main.cpp'
691--- src/main.cpp 2014-08-12 22:06:14 +0000
692+++ src/main.cpp 2014-09-30 16:43:01 +0000
693@@ -76,7 +76,7 @@
694 }
695
696 galera::AddressBook book;
697- QObject::connect(&book, &galera::AddressBook::ready, [&book] () { onServiceReady(&book); });
698+ QObject::connect(&book, &galera::AddressBook::readyChanged, [&book] () { onServiceReady(&book); });
699 app.connect(&book, SIGNAL(stopped()), SLOT(quit()));
700
701 if (book.start()) {
702
703=== added file 'upstart/CMakeLists.txt'
704--- upstart/CMakeLists.txt 1970-01-01 00:00:00 +0000
705+++ upstart/CMakeLists.txt 2014-09-30 16:43:01 +0000
706@@ -0,0 +1,5 @@
707+configure_file(address-book-service.conf.in ${CMAKE_CURRENT_BINARY_DIR}/address-book-service.conf)
708+
709+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/address-book-service.conf
710+ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/upstart/sessions/)
711+
712
713=== renamed file 'upstart/address-book-service.conf' => 'upstart/address-book-service.conf.in'
714--- upstart/address-book-service.conf 2014-09-11 18:56:47 +0000
715+++ upstart/address-book-service.conf.in 2014-09-30 16:43:01 +0000
716@@ -5,7 +5,6 @@
717 stop on runlevel [06]
718
719 respawn
720-respawn limit unlimited
721
722 pre-start script
723 echo "START `date`"
724@@ -16,4 +15,4 @@
725 echo "STOP `date`"
726 end script
727
728-exec /usr/lib/arm-linux-gnueabihf/address-book-service/address-book-service
729+exec @CMAKE_INSTALL_FULL_LIBEXECDIR@/address-book-service

Subscribers

People subscribed via source and target branches