Commit ae7ee350 authored by Carlos Garnacho's avatar Carlos Garnacho Committed by Carlos Garnacho

Propagate index errors up to the GUI, so the user has the opportunity to

2009-04-07  Carlos Garnacho  <carlos@imendio.com>

        Propagate index errors up to the GUI, so the user has the opportunity
        to trigger a reindex.

        * src/libtracker-db/tracker-db-index.[ch]: Add an "error-received"
        signal. Emit it when QDBM fails to store a word.

        * data/dbus/tracker-indexer.xml:
        * src/tracker-indexer/tracker-marshal.list:
        * src/tracker-indexer/tracker-indexer.[ch]: Add an "IndexingError"
        DBus signal. Propagate up index errors.

        * data/dbus/tracker-daemon.xml:
        * src/trackerd/tracker-dbus.c:
        * src/trackerd/tracker-daemon.c:
        * src/trackerd/tracker-marshal.list: Add an "IndexingError" signal.
        Listen to that signal from the indexer in order to propagate it up the
        stack.

        src/tracker-applet/tracker-applet.[ch]: Listen for the new signal, and
        display an error notification with an option to reindex from scratch.

svn path=/trunk/; revision=3184
parent c074df68
2009-04-07 Carlos Garnacho <carlos@imendio.com>
Propagate index errors up to the GUI, so the user has the opportunity
to trigger a reindex.
* src/libtracker-db/tracker-db-index.[ch]: Add an "error-received"
signal. Emit it when QDBM fails to store a word.
* data/dbus/tracker-indexer.xml:
* src/tracker-indexer/tracker-marshal.list:
* src/tracker-indexer/tracker-indexer.[ch]: Add an "IndexingError"
DBus signal. Propagate up index errors.
* data/dbus/tracker-daemon.xml:
* src/trackerd/tracker-dbus.c:
* src/trackerd/tracker-daemon.c:
* src/trackerd/tracker-marshal.list: Add an "IndexingError" signal.
Listen to that signal from the indexer in order to propagate it up the
stack.
src/tracker-applet/tracker-applet.[ch]: Listen for the new signal, and
display an error notification with an option to reindex from scratch.
2009-04-07 Mikael Ottela <mikael.ottela@ixonos.com>
* tests/tracker-extract/tracker-extract-png-test.c
......
......@@ -180,6 +180,11 @@
<arg type="d" name="seconds_elapsed"/>
</signal>
<signal name="IndexingError">
<arg type="s" name="reason" />
<arg type="b" name="requires_reindex" />
</signal>
<!-- Signal whenever the count of a category changed. Look at GetStats for
the format of service_stats.
-->
......
......@@ -102,5 +102,9 @@
<signal name="ModuleFinished">
<arg type="s" name="module_name" />
</signal>
<signal name="IndexingError">
<arg type="s" name="reason" />
<arg type="b" name="requires_reindexing" />
</signal>
</interface>
</node>
......@@ -26,6 +26,7 @@
#include <depot.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <libtracker-common/tracker-log.h>
......@@ -40,6 +41,8 @@
#define MAX_CACHE_DEPTH 2
#define MAX_FLUSH_TIME 0.5 /* In fractions of a second */
#define TRACKER_DB_INDEX_ERROR_DOMAIN "TrackerDBIndex"
#define TRACKER_DB_INDEX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_DB_INDEX, TrackerDBIndexPrivate))
typedef struct TrackerDBIndexPrivate TrackerDBIndexPrivate;
......@@ -90,6 +93,13 @@ enum {
PROP_OVERLOADED
};
enum {
ERROR_RECEIVED,
LAST_SIGNAL
};
static guint signals [LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (TrackerDBIndex, tracker_db_index, G_TYPE_OBJECT)
static void
......@@ -160,6 +170,15 @@ tracker_db_index_class_init (TrackerDBIndexClass *klass)
"Whether the index cache is overloaded",
FALSE,
G_PARAM_READABLE));
signals[ERROR_RECEIVED] =
g_signal_new ("error-received",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (TrackerDBIndexClass, error_received),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
g_type_class_add_private (object_class, sizeof (TrackerDBIndexPrivate));
}
......@@ -597,6 +616,20 @@ update_overloaded_status (TrackerDBIndex *indez)
}
}
static void
emit_error_received (TrackerDBIndex *indez,
const gchar *error_str)
{
GQuark domain;
GError *error;
domain = g_quark_from_static_string (TRACKER_DB_INDEX_ERROR_DOMAIN);
error = g_error_new_literal (domain, 0, error_str);
g_signal_emit (indez, signals[ERROR_RECEIVED], 0, error);
g_error_free (error);
}
/* Use for deletes or updates of multiple entities when they are not
* new.
*/
......@@ -813,6 +846,9 @@ index_flush_item (gpointer user_data)
/* Process words from cache */
if (indexer_update_word (key, value, priv->index)) {
g_hash_table_iter_remove (&iter);
} else {
emit_error_received (indez, _("Index corrupted"));
break;
}
if (g_timer_elapsed (timer, NULL) > MAX_FLUSH_TIME) {
......
......@@ -46,6 +46,9 @@ struct TrackerDBIndex {
struct TrackerDBIndexClass {
GObjectClass parent_class;
void (* error_received) (TrackerDBIndex *indez,
GError *error);
};
GType tracker_db_index_get_type (void);
......
......@@ -188,6 +188,7 @@ static void set_auto_pause (TrayIcon *icon,
gboolean pause);
static TrayIcon *main_icon;
static NotifyNotification *error_notification = NULL;
static const gchar *index_icons[4] = {
"tracker-applet-default.png",
......@@ -1578,6 +1579,18 @@ index_finished (DBusGProxy *proxy,
stop_watching_events (icon);
}
static void
index_error (DBusGProxy *proxy,
const gchar *reason,
gboolean requires_reindex,
TrayIcon *icon)
{
tray_icon_show_error (icon, requires_reindex,
"%s\n\n%s",
_("There was an error while performing indexing:"),
reason);
}
static void
index_service_stats_updated (DBusGProxy *proxy,
GPtrArray *new_stats,
......@@ -1865,6 +1878,11 @@ setup_dbus_connection (TrayIcon *icon)
G_TYPE_INT,
G_TYPE_DOUBLE,
G_TYPE_INVALID);
dbus_g_object_register_marshaller (tracker_marshal_VOID__STRING_BOOLEAN,
G_TYPE_NONE,
G_TYPE_STRING,
G_TYPE_BOOLEAN,
G_TYPE_INVALID);
dbus_g_proxy_add_signal (priv->tracker->proxy,
"IndexStateChange",
......@@ -1897,6 +1915,12 @@ setup_dbus_connection (TrayIcon *icon)
TRACKER_TYPE_G_STRV_ARRAY,
G_TYPE_INVALID);
dbus_g_proxy_add_signal (priv->tracker->proxy,
"IndexingError",
G_TYPE_STRING,
G_TYPE_BOOLEAN,
G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->tracker->proxy,
"IndexStateChange",
G_CALLBACK (index_state_changed),
......@@ -1914,6 +1938,11 @@ setup_dbus_connection (TrayIcon *icon)
G_CALLBACK (index_finished),
icon,
NULL);
dbus_g_proxy_connect_signal (priv->tracker->proxy,
"IndexingError",
G_CALLBACK (index_error),
icon,
NULL);
dbus_g_proxy_connect_signal (priv->tracker->proxy,
"ServiceStatisticsUpdated",
......@@ -2058,6 +2087,68 @@ tray_icon_show_message (TrayIcon *icon,
g_free (msg);
}
static void
error_notification_reindex_cb (NotifyNotification *notification,
const gchar *action,
gpointer user_data)
{
reindex (NULL, user_data);
}
static void
error_notification_closed_cb (NotifyNotification *notification,
gpointer user_data)
{
g_object_unref (error_notification);
error_notification = NULL;
}
void
tray_icon_show_error (TrayIcon *icon,
gboolean requires_reindex,
const gchar *message,
...)
{
TrayIconPrivate *priv;
gchar *msg = NULL;
va_list args;
if (error_notification) {
/* There's already an error being displayed */
return;
}
priv = TRAY_ICON_GET_PRIVATE (icon);
va_start (args, message);
msg = g_strdup_vprintf (message, args);
va_end (args);
error_notification =
notify_notification_new_with_status_icon ("Tracker",
msg,
NULL,
priv->icon);
notify_notification_set_timeout (error_notification, NOTIFY_EXPIRES_NEVER);
notify_notification_set_urgency (error_notification, NOTIFY_URGENCY_CRITICAL);
g_signal_connect (error_notification, "closed",
G_CALLBACK (error_notification_closed_cb), NULL);
if (requires_reindex) {
notify_notification_add_action (error_notification,
"reindex",
_("Reindex all contents"),
NOTIFY_ACTION_CALLBACK (error_notification_reindex_cb),
icon, NULL);
}
notify_notification_show (error_notification, NULL);
g_free (msg);
}
GType
tray_icon_get_type (void)
{
......
......@@ -51,5 +51,9 @@ tray_icon_set_tooltip (TrayIcon *icon, const gchar *format, ...);
void
tray_icon_show_message (TrayIcon *icon, const gchar *message, ...);
void
tray_icon_show_error (TrayIcon *icon, gboolean requires_reindex, const gchar *message, ...);
#endif
......@@ -82,7 +82,7 @@
#define TRACKER_INDEXER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_INDEXER, TrackerIndexerPrivate))
#define FILES_REMAINING_THRESHOLD 10000
#define FILES_REMAINING_THRESHOLD 1000
#define MAX_FLUSH_FREQUENCY 60
#define MIN_FLUSH_FREQUENCY 1
......@@ -198,6 +198,7 @@ enum {
MODULE_FINISHED,
PAUSED,
CONTINUED,
INDEXING_ERROR,
LAST_SIGNAL
};
......@@ -525,6 +526,15 @@ index_overloaded_notify_cb (GObject *object,
}
}
static void
index_error_received_cb (TrackerDBIndex *index,
const GError *error,
TrackerIndexer *indexer)
{
g_signal_emit (indexer, signals[INDEXING_ERROR], 0,
error->message, TRUE);
}
static void
check_mount_removal (GQueue *queue,
GFile *mount_root,
......@@ -773,6 +783,15 @@ tracker_indexer_class_init (TrackerIndexerClass *class)
G_TYPE_NONE,
1,
G_TYPE_STRING);
signals[INDEXING_ERROR] =
g_signal_new ("indexing-error",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (TrackerIndexerClass, indexing_error),
NULL, NULL,
tracker_marshal_VOID__STRING_BOOL,
G_TYPE_NONE,
2, G_TYPE_STRING, G_TYPE_BOOLEAN);
g_object_class_install_property (object_class,
PROP_RUNNING,
......@@ -1041,6 +1060,8 @@ tracker_indexer_init (TrackerIndexer *indexer)
G_CALLBACK (index_flushing_notify_cb), indexer);
g_signal_connect (priv->file_index, "notify::overloaded",
G_CALLBACK (index_overloaded_notify_cb), indexer);
g_signal_connect (priv->file_index, "error-received",
G_CALLBACK (index_error_received_cb), indexer);
lindex = tracker_db_index_manager_get_index (TRACKER_DB_INDEX_EMAIL);
priv->email_index = g_object_ref (lindex);
......@@ -1049,6 +1070,8 @@ tracker_indexer_init (TrackerIndexer *indexer)
G_CALLBACK (index_flushing_notify_cb), indexer);
g_signal_connect (priv->email_index, "notify::overloaded",
G_CALLBACK (index_overloaded_notify_cb), indexer);
g_signal_connect (priv->email_index, "error-received",
G_CALLBACK (index_error_received_cb), indexer);
/* Set up databases, these pointers are mostly used to
* start/stop transactions, since TrackerDBManager treats
......
......@@ -73,6 +73,9 @@ struct TrackerIndexerClass {
const gchar *module_name);
void (*module_finished) (TrackerIndexer *indexer,
const gchar *module_name);
void (*indexing_error) (TrackerIndexer *indexer,
const gchar *reason,
gboolean requires_reindex);
};
GType tracker_indexer_get_type (void) G_GNUC_CONST;
......
VOID:DOUBLE,UINT,UINT,BOOL
VOID:DOUBLE,STRING,UINT,UINT,UINT
VOID:STRING,BOOL
......@@ -58,6 +58,7 @@ enum {
INDEX_STATE_CHANGE,
INDEX_FINISHED,
INDEX_PROGRESS,
INDEXING_ERROR,
SERVICE_STATISTICS_UPDATED,
LAST_SIGNAL
};
......@@ -118,6 +119,14 @@ tracker_daemon_class_init (TrackerDaemonClass *klass)
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_DOUBLE);
signals[INDEXING_ERROR] =
g_signal_new ("indexing-error",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
tracker_marshal_VOID__STRING_BOOLEAN,
G_TYPE_NONE,
2, G_TYPE_STRING, G_TYPE_BOOLEAN);
signals[SERVICE_STATISTICS_UPDATED] =
g_signal_new ("service-statistics-updated",
G_TYPE_FROM_CLASS (klass),
......@@ -142,6 +151,16 @@ indexer_finished_cb (DBusGProxy *proxy,
tracker_daemon_signal_statistics ();
}
static void
indexing_error_cb (DBusGProxy *proxy,
const gchar *reason,
gboolean requires_reindex,
TrackerDaemon *daemon)
{
g_signal_emit (daemon, signals[INDEXING_ERROR], 0,
reason, requires_reindex);
}
static void
tracker_daemon_init (TrackerDaemon *object)
{
......@@ -158,6 +177,10 @@ tracker_daemon_init (TrackerDaemon *object)
G_CALLBACK (indexer_finished_cb),
object,
NULL);
dbus_g_proxy_connect_signal (proxy, "IndexingError",
G_CALLBACK (indexing_error_cb),
object,
NULL);
iface = tracker_db_manager_get_db_interface_by_service (TRACKER_DB_FOR_FILE_SERVICE);
......
......@@ -477,6 +477,11 @@ tracker_dbus_indexer_get_proxy (void)
G_TYPE_UINT,
G_TYPE_BOOLEAN,
G_TYPE_INVALID);
dbus_g_object_register_marshaller (tracker_marshal_VOID__STRING_BOOLEAN,
G_TYPE_NONE,
G_TYPE_STRING,
G_TYPE_BOOLEAN,
G_TYPE_INVALID);
/* Add signals, why can't we use introspection for this? */
dbus_g_proxy_add_signal (proxy_for_indexer,
......@@ -512,6 +517,11 @@ tracker_dbus_indexer_get_proxy (void)
"ModuleFinished",
G_TYPE_STRING,
G_TYPE_INVALID);
dbus_g_proxy_add_signal (proxy_for_indexer,
"IndexingError",
G_TYPE_STRING,
G_TYPE_BOOLEAN,
G_TYPE_INVALID);
}
return proxy_for_indexer;
......
VOID:STRING,UINT,UINT,UINT,UINT
VOID:STRING,STRING,INT,INT,INT,DOUBLE
VOID:STRING,STRING,STRING
VOID:STRING,BOOLEAN
VOID:STRING,BOOLEAN,BOOLEAN,BOOLEAN,BOOLEAN,BOOLEAN,BOOLEAN
VOID:STRING,OBJECT,BOOLEAN
VOID:STRING,OBJECT,OBJECT,BOOLEAN,BOOLEAN
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment