[tracker/avoid-duplicates] Fixes NB#175723: Avoid duplicates if several monitor events arrive together and store is slow
- From: Aleksander Morgado <aleksm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/avoid-duplicates] Fixes NB#175723: Avoid duplicates if several monitor events arrive together and store is slow
- Date: Wed, 23 Jun 2010 12:53:36 +0000 (UTC)
commit 9dc4772017992772b7b8c839d0ee53727f5e51d4
Author: Aleksander Morgado <aleksander lanedo com>
Date: Wed Jun 23 14:20:03 2010 +0200
Fixes NB#175723: Avoid duplicates if several monitor events arrive together and store is slow
* If a given file is being currently processed (in the processing_pool), a new event
on the same file must not be launched. Instead, the event is scheduled to be added
again in the proper queue after 2 seconds.
src/libtracker-miner/tracker-miner-fs.c | 128 +++++++++++++++++++++++++++----
1 files changed, 113 insertions(+), 15 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c
index 5a2ebaa..3a3cbf1 100644
--- a/src/libtracker-miner/tracker-miner-fs.c
+++ b/src/libtracker-miner/tracker-miner-fs.c
@@ -47,12 +47,21 @@
#define TRACKER_MINER_FS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MINER_FS, TrackerMinerFSPrivate))
+/* Seconds to postpone a given event */
+#define EVENT_POSTPONED_INTERVAL 2
+
typedef struct {
GFile *file;
GFile *source_file;
} ItemMovedData;
typedef struct {
+ TrackerMinerFS *fs;
+ GQueue *queue;
+ gpointer item;
+} ItemEventPostponedData;
+
+typedef struct {
GFile *file;
guint recurse : 1;
guint ref_count : 7;
@@ -214,6 +223,9 @@ static DirectoryData *directory_data_new (GFile
gboolean recurse);
static DirectoryData *directory_data_ref (DirectoryData *dd);
static void directory_data_unref (DirectoryData *dd);
+static void item_add_to_queue_postponed (TrackerMinerFS *fs,
+ GQueue *queue,
+ gpointer item);
static ItemMovedData *item_moved_data_new (GFile *file,
GFile *source_file);
static void item_moved_data_free (ItemMovedData *data);
@@ -612,21 +624,31 @@ process_data_free (ProcessData *data)
static ProcessData *
process_data_find (TrackerMinerFS *fs,
- GFile *file)
+ GFile *file,
+ gboolean path_search)
{
GList *l;
for (l = fs->private->processing_pool; l; l = l->next) {
ProcessData *data = l->data;
- /* Different operations for the same file URI could be
- * piled up here, each being a different GFile object.
- * Miner implementations should really notify on the
- * same GFile object that's being passed, so we check for
- * pointer equality here, rather than doing path comparisons
- */
- if (data->file == file) {
- return data;
+ if (!path_search) {
+ /* Different operations for the same file URI could be
+ * piled up here, each being a different GFile object.
+ * Miner implementations should really notify on the
+ * same GFile object that's being passed, so we check for
+ * pointer equality here, rather than doing path comparisons
+ */
+ if(data->file == file)
+ return data;
+ } else {
+ /* Note that if there are different GFiles being
+ * processed for the same file path, we are actually
+ * returning the first one found, If you want exactly
+ * the same GFile as the one as input, use the
+ * process_data_find() method instead */
+ if (g_file_equal (data->file, file))
+ return data;
}
}
@@ -1321,7 +1343,7 @@ do_process_file (TrackerMinerFS *fs,
/* Re-fetch data, since it might have been
* removed in broken implementations
*/
- data = process_data_find (fs, data->file);
+ data = process_data_find (fs, data->file, FALSE);
g_message ("%s refused to process '%s'", G_OBJECT_TYPE_NAME (fs), uri);
@@ -1962,6 +1984,14 @@ item_queue_get_next_file (TrackerMinerFS *fs,
*file = NULL;
return QUEUE_IGNORE_NEXT_UPDATE;
}
+ if (process_data_find (fs, queue_file, TRUE)) {
+ *file = NULL;
+ /* Need to postpone event... */
+ item_add_to_queue_postponed (fs,
+ fs->private->items_deleted,
+ queue_file); /* no need to ref again */
+ return QUEUE_WAIT;
+ }
*file = queue_file;
return QUEUE_DELETED;
}
@@ -1999,6 +2029,14 @@ item_queue_get_next_file (TrackerMinerFS *fs,
*source_file = queue_file;
return QUEUE_IGNORE_NEXT_UPDATE;
}
+ if (process_data_find (fs, queue_file, TRUE)) {
+ *file = NULL;
+ /* Need to postpone event... */
+ item_add_to_queue_postponed (fs,
+ fs->private->items_created,
+ queue_file); /* no need to ref again */
+ return QUEUE_WAIT;
+ }
*file = queue_file;
*source_file = NULL;
return QUEUE_CREATED;
@@ -2011,6 +2049,14 @@ item_queue_get_next_file (TrackerMinerFS *fs,
*source_file = NULL;
if (check_ignore_next_update (fs, queue_file))
return QUEUE_IGNORE_NEXT_UPDATE;
+ if (process_data_find (fs, queue_file, TRUE)) {
+ *file = NULL;
+ /* Need to postpone event... */
+ item_add_to_queue_postponed (fs,
+ fs->private->items_updated,
+ queue_file); /* no need to ref again */
+ return QUEUE_WAIT;
+ }
return QUEUE_UPDATED;
}
@@ -2019,9 +2065,23 @@ item_queue_get_next_file (TrackerMinerFS *fs,
if (data) {
*file = g_object_ref (data->file);
*source_file = g_object_ref (data->source_file);
- item_moved_data_free (data);
- if (check_ignore_next_update (fs, *file))
+ if (check_ignore_next_update (fs, *file)) {
+ item_moved_data_free (data);
return QUEUE_IGNORE_NEXT_UPDATE;
+ }
+ if (process_data_find (fs, *file, TRUE) ||
+ process_data_find (fs, *source_file, TRUE)) {
+ g_object_unref (*file);
+ g_object_unref (*source_file);
+ *file = NULL;
+ *source_file = NULL;
+ /* Need to postpone event... */
+ item_add_to_queue_postponed (fs,
+ fs->private->items_moved,
+ data); /* no need to create again */
+ return QUEUE_WAIT;
+ }
+ item_moved_data_free (data);
return QUEUE_MOVED;
}
@@ -2511,6 +2571,44 @@ should_process_file (TrackerMinerFS *fs,
return should_change_index_for_file (fs, file);
}
+static gboolean
+item_event_postponed_cb (gpointer data)
+{
+ ItemEventPostponedData *event = data;
+
+ g_debug ("Running postponed event %p...", event);
+
+ g_queue_push_tail (event->queue, event->item);
+ item_queue_handlers_set_up (event->fs);
+
+ g_slice_free (ItemEventPostponedData, event);
+
+ return FALSE;
+}
+
+static void
+item_add_to_queue_postponed (TrackerMinerFS *fs,
+ GQueue *queue,
+ gpointer item)
+{
+ /* Event should be postponed because it's already being processed at
+ * this moment, so schedule it to be added to the proper queue after
+ * some seconds */
+ ItemEventPostponedData *event;
+
+ event = g_slice_new (ItemEventPostponedData);
+ event->queue = queue;
+ event->item = item;
+ event->fs = fs;
+
+ g_debug ("Postponing event %p for %u seconds...",
+ event,
+ EVENT_POSTPONED_INTERVAL);
+ g_timeout_add_seconds (EVENT_POSTPONED_INTERVAL,
+ item_event_postponed_cb,
+ event);
+}
+
static void
monitor_item_created_cb (TrackerMonitor *monitor,
GFile *file,
@@ -3380,7 +3478,7 @@ tracker_miner_fs_file_notify (TrackerMinerFS *fs,
fs->private->total_files_notified++;
- data = process_data_find (fs, file);
+ data = process_data_find (fs, file, FALSE);
if (!data) {
gchar *uri;
@@ -3482,7 +3580,7 @@ tracker_miner_fs_get_urn (TrackerMinerFS *fs,
g_return_val_if_fail (TRACKER_IS_MINER_FS (fs), NULL);
g_return_val_if_fail (G_IS_FILE (file), NULL);
- data = process_data_find (fs, file);
+ data = process_data_find (fs, file, FALSE);
if (!data) {
gchar *uri;
@@ -3523,7 +3621,7 @@ tracker_miner_fs_get_parent_urn (TrackerMinerFS *fs,
g_return_val_if_fail (TRACKER_IS_MINER_FS (fs), NULL);
g_return_val_if_fail (G_IS_FILE (file), NULL);
- data = process_data_find (fs, file);
+ data = process_data_find (fs, file, FALSE);
if (!data) {
gchar *uri;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]