Merge lp:~charlesk/indicator-datetime/lp-1306112-query-eds-less-frequently-if-load-is-heavy into lp:indicator-datetime/14.04

Proposed by Charles Kerr
Status: Merged
Approved by: Bill Filler
Approved revision: 344
Merged at revision: 339
Proposed branch: lp:~charlesk/indicator-datetime/lp-1306112-query-eds-less-frequently-if-load-is-heavy
Merge into: lp:indicator-datetime/14.04
Diff against target: 262 lines (+78/-96)
4 files modified
include/datetime/appointment.h (+0/-2)
src/appointment.cpp (+0/-1)
src/engine-eds.cpp (+78/-91)
tests/manual-test-snap.cpp (+0/-2)
To merge this branch: bzr merge lp:~charlesk/indicator-datetime/lp-1306112-query-eds-less-frequently-if-load-is-heavy
Reviewer Review Type Date Requested Status
Bill Filler (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Renato Araujo Oliveira Filho Pending
Review via email: mp+215497@code.launchpad.net

Commit message

If there's a large batch of EDS events coming in, try to wait until the event storm has passed before running our requery.

Description of the change

If there's a large batch of EDS events coming in, try to wait until the event storm has passed before running our requery.

Previously we re-queried after an interval of 200 msec. This patch progressively widens that window until the event storm subsides, or until a minute has passed, whichever comes first.

Made in collaboration w/Renato.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
340. By Charles Kerr

remove some extraneous EDS events on startup

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
341. By Charles Kerr

remove unused field Appointment.is_event

342. By Charles Kerr

remove unused field Appointment.is_daily

343. By Charles Kerr

sync with lp:~renatofilho/qtorganizer5-eds/fix-1284375's method of storing alarm urls. Happily this supercedes our code that used to call e_cal_client_get_attachment_uris(), so this means fewer round trip calls to EDS

344. By Charles Kerr

copyediting: fix indentation/formatting

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)
Revision history for this message
Bill Filler (bfiller) wrote :

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
=== modified file 'include/datetime/appointment.h'
--- include/datetime/appointment.h 2014-01-30 19:00:22 +0000
+++ include/datetime/appointment.h 2014-04-15 16:12:38 +0000
@@ -39,8 +39,6 @@
39 std::string summary;39 std::string summary;
40 std::string url;40 std::string url;
41 std::string uid;41 std::string uid;
42 bool is_event = false;
43 bool is_daily = false;
44 bool has_alarms = false;42 bool has_alarms = false;
45 DateTime begin;43 DateTime begin;
46 DateTime end;44 DateTime end;
4745
=== modified file 'src/appointment.cpp'
--- src/appointment.cpp 2014-01-30 19:00:22 +0000
+++ src/appointment.cpp 2014-04-15 16:12:38 +0000
@@ -33,7 +33,6 @@
33 && (summary==that.summary)33 && (summary==that.summary)
34 && (url==that.url)34 && (url==that.url)
35 && (uid==that.uid)35 && (uid==that.uid)
36 && (is_event==that.is_event)
37 && (has_alarms==that.has_alarms)36 && (has_alarms==that.has_alarms)
38 && (begin==that.begin)37 && (begin==that.begin)
39 && (end==that.end);38 && (end==that.end);
4039
=== modified file 'src/engine-eds.cpp'
--- src/engine-eds.cpp 2014-03-10 02:08:47 +0000
+++ src/engine-eds.cpp 2014-04-15 16:12:38 +0000
@@ -25,6 +25,7 @@
25#include <libedataserver/libedataserver.h>25#include <libedataserver/libedataserver.h>
2626
27#include <algorithm> // std::sort()27#include <algorithm> // std::sort()
28#include <ctime> // time()
28#include <map>29#include <map>
29#include <set>30#include <set>
3031
@@ -144,16 +145,29 @@
144 {145 {
145 auto self = static_cast<Impl*>(gself);146 auto self = static_cast<Impl*>(gself);
146 self->m_rebuild_tag = 0;147 self->m_rebuild_tag = 0;
148 self->m_rebuild_deadline = 0;
147 self->set_dirty_now();149 self->set_dirty_now();
148 return G_SOURCE_REMOVE;150 return G_SOURCE_REMOVE;
149 }151 }
150152
151 void set_dirty_soon()153 void set_dirty_soon()
152 {154 {
153 static const int ARBITRARY_BATCH_MSEC = 200;155 static constexpr int MIN_BATCH_SEC = 1;
154156 static constexpr int MAX_BATCH_SEC = 60;
155 if (m_rebuild_tag == 0)157 static_assert(MIN_BATCH_SEC <= MAX_BATCH_SEC, "bad boundaries");
156 m_rebuild_tag = g_timeout_add(ARBITRARY_BATCH_MSEC, set_dirty_now_static, this);158
159 const auto now = time(nullptr);
160
161 if (m_rebuild_deadline == 0) // first pass
162 {
163 m_rebuild_deadline = now + MAX_BATCH_SEC;
164 m_rebuild_tag = g_timeout_add_seconds(MIN_BATCH_SEC, set_dirty_now_static, this);
165 }
166 else if (now < m_rebuild_deadline)
167 {
168 g_source_remove (m_rebuild_tag);
169 m_rebuild_tag = g_timeout_add_seconds(MIN_BATCH_SEC, set_dirty_now_static, this);
170 }
157 }171 }
158172
159 static void on_source_registry_ready(GObject* /*source*/, GAsyncResult* res, gpointer gself)173 static void on_source_registry_ready(GObject* /*source*/, GAsyncResult* res, gpointer gself)
@@ -272,6 +286,7 @@
272 if (e_cal_client_get_view_finish (E_CAL_CLIENT(client), res, &view, &error))286 if (e_cal_client_get_view_finish (E_CAL_CLIENT(client), res, &view, &error))
273 {287 {
274 // add the view to our collection288 // add the view to our collection
289 e_cal_client_view_set_flags(view, E_CAL_CLIENT_VIEW_FLAGS_NONE, NULL);
275 e_cal_client_view_start(view, &error);290 e_cal_client_view_start(view, &error);
276 g_debug("got a view for %s", e_cal_client_get_local_attachment_store(E_CAL_CLIENT(client)));291 g_debug("got a view for %s", e_cal_client_get_local_attachment_store(E_CAL_CLIENT(client)));
277 auto self = static_cast<Impl*>(gself);292 auto self = static_cast<Impl*>(gself);
@@ -386,14 +401,6 @@
386 }401 }
387 };402 };
388403
389 struct UrlSubtask
390 {
391 std::shared_ptr<Task> task;
392 Appointment appointment;
393 UrlSubtask(const std::shared_ptr<Task>& task_in, const Appointment& appointment_in):
394 task(task_in), appointment(appointment_in) {}
395 };
396
397 static gboolean404 static gboolean
398 my_get_appointments_foreach(ECalComponent* component,405 my_get_appointments_foreach(ECalComponent* component,
399 time_t begin,406 time_t begin,
@@ -405,89 +412,68 @@
405412
406 if ((vtype == E_CAL_COMPONENT_EVENT) || (vtype == E_CAL_COMPONENT_TODO))413 if ((vtype == E_CAL_COMPONENT_EVENT) || (vtype == E_CAL_COMPONENT_TODO))
407 {414 {
408 const gchar* uid = nullptr;415 const gchar* uid = nullptr;
409 e_cal_component_get_uid(component, &uid);416 e_cal_component_get_uid(component, &uid);
410417
411 auto status = ICAL_STATUS_NONE;418 auto status = ICAL_STATUS_NONE;
412 e_cal_component_get_status(component, &status);419 e_cal_component_get_status(component, &status);
413420
414 if ((uid != nullptr) &&421 if ((uid != nullptr) &&
415 (status != ICAL_STATUS_COMPLETED) &&422 (status != ICAL_STATUS_COMPLETED) &&
416 (status != ICAL_STATUS_CANCELLED))423 (status != ICAL_STATUS_CANCELLED))
417 {424 {
418 Appointment appointment;425 Appointment appointment;
419426
420 /* Determine whether this is a recurring event.427 ECalComponentText text;
421 NB: icalrecurrencetype supports complex recurrence patterns;428 text.value = nullptr;
422 however, since design only allows daily recurrence,429 e_cal_component_get_summary(component, &text);
423 that's all we support here. */430 if (text.value)
424 GSList * recur_list;431 appointment.summary = text.value;
425 e_cal_component_get_rrule_list(component, &recur_list);432
426 for (auto l=recur_list; l!=nullptr; l=l->next)433 appointment.begin = DateTime(begin);
427 {434 appointment.end = DateTime(end);
428 const auto recur = static_cast<struct icalrecurrencetype*>(l->data);435 appointment.color = subtask->color;
429 appointment.is_daily |= ((recur->freq == ICAL_DAILY_RECURRENCE)436 appointment.uid = uid;
430 && (recur->interval == 1));437
431 }438 // if the component has display alarms that have a url,
432 e_cal_component_free_recur_list(recur_list);439 // use the first one as our Appointment.url
433440 auto alarm_uids = e_cal_component_get_alarm_uids(component);
434 ECalComponentText text;441 appointment.has_alarms = alarm_uids != nullptr;
435 text.value = nullptr;442 for(auto walk=alarm_uids; appointment.url.empty() && walk!=nullptr; walk=walk->next)
436 e_cal_component_get_summary(component, &text);443 {
437 if (text.value)444 auto alarm = e_cal_component_get_alarm(component, static_cast<const char*>(walk->data));
438 appointment.summary = text.value;445
439446 ECalComponentAlarmAction action;
440 appointment.begin = DateTime(begin);447 e_cal_component_alarm_get_action(alarm, &action);
441 appointment.end = DateTime(end);448 if (action == E_CAL_COMPONENT_ALARM_DISPLAY)
442 appointment.color = subtask->color;449 {
443 appointment.is_event = vtype == E_CAL_COMPONENT_EVENT;450 icalattach* attach = nullptr;
444 appointment.uid = uid;451 e_cal_component_alarm_get_attach(alarm, &attach);
445452 if (attach != nullptr)
446 GList * alarm_uids = e_cal_component_get_alarm_uids(component);453 {
447 appointment.has_alarms = alarm_uids != nullptr;454 if (icalattach_get_is_url (attach))
448 cal_obj_uid_list_free(alarm_uids);455 {
449456 const char* url = icalattach_get_url(attach);
450 e_cal_client_get_attachment_uris(subtask->client,457 if (url != nullptr)
451 uid,458 appointment.url = url;
452 nullptr,459 }
453 subtask->task->p->m_cancellable,460
454 on_appointment_uris_ready,461 icalattach_unref(attach);
455 new UrlSubtask(subtask->task, appointment));462 }
463 }
464
465 e_cal_component_alarm_free(alarm);
466 }
467 cal_obj_uid_list_free(alarm_uids);
468
469 g_debug("adding appointment '%s' '%s'", appointment.summary.c_str(), appointment.url.c_str());
470 subtask->task->appointments.push_back(appointment);
456 }471 }
457 }472 }
458473
459 return G_SOURCE_CONTINUE;474 return G_SOURCE_CONTINUE;
460 }475 }
461476
462 static void on_appointment_uris_ready(GObject* client, GAsyncResult* res, gpointer gsubtask)
463 {
464 auto subtask = static_cast<UrlSubtask*>(gsubtask);
465
466 GSList * uris = nullptr;
467 GError * error = nullptr;
468 e_cal_client_get_attachment_uris_finish(E_CAL_CLIENT(client), res, &uris, &error);
469 if (error != nullptr)
470 {
471 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
472 !g_error_matches(error, E_CLIENT_ERROR, E_CLIENT_ERROR_NOT_SUPPORTED))
473 {
474 g_warning("Error getting appointment uris: %s", error->message);
475 }
476
477 g_error_free(error);
478 }
479 else if (uris != nullptr)
480 {
481 subtask->appointment.url = (const char*) uris->data; // copy the first URL
482 g_debug("found url '%s' for appointment '%s'", subtask->appointment.url.c_str(), subtask->appointment.summary.c_str());
483 e_client_util_free_string_slist(uris);
484 }
485
486 g_debug("adding appointment '%s' '%s'", subtask->appointment.summary.c_str(), subtask->appointment.url.c_str());
487 subtask->task->appointments.push_back(subtask->appointment);
488 delete subtask;
489 }
490
491 EdsEngine& m_owner;477 EdsEngine& m_owner;
492 core::Signal<> m_changed;478 core::Signal<> m_changed;
493 std::set<ESource*> m_sources;479 std::set<ESource*> m_sources;
@@ -496,6 +482,7 @@
496 GCancellable* m_cancellable = nullptr;482 GCancellable* m_cancellable = nullptr;
497 ESourceRegistry* m_source_registry = nullptr;483 ESourceRegistry* m_source_registry = nullptr;
498 guint m_rebuild_tag = 0;484 guint m_rebuild_tag = 0;
485 time_t m_rebuild_deadline = 0;
499};486};
500487
501/***488/***
502489
=== modified file 'tests/manual-test-snap.cpp'
--- tests/manual-test-snap.cpp 2014-02-04 19:00:22 +0000
+++ tests/manual-test-snap.cpp 2014-04-15 16:12:38 +0000
@@ -36,8 +36,6 @@
36 a.summary = "Alarm";36 a.summary = "Alarm";
37 a.url = "alarm:///hello-world";37 a.url = "alarm:///hello-world";
38 a.uid = "D4B57D50247291478ED31DED17FF0A9838DED402";38 a.uid = "D4B57D50247291478ED31DED17FF0A9838DED402";
39 a.is_event = false;
40 a.is_daily = false;
41 a.has_alarms = true;39 a.has_alarms = true;
42 auto begin = g_date_time_new_local(2014,12,25,0,0,0);40 auto begin = g_date_time_new_local(2014,12,25,0,0,0);
43 auto end = g_date_time_add_full(begin,0,0,1,0,0,-1);41 auto end = g_date_time_add_full(begin,0,0,1,0,0,-1);

Subscribers

People subscribed via source and target branches