summaryrefslogtreecommitdiff
path: root/tumblerd
diff options
context:
space:
mode:
authorGaël Bonithon <gael@xfce.org>2021-12-28 16:20:37 +0100
committerGaël Bonithon <gael@xfce.org>2021-12-29 13:09:43 +0100
commita188f1c30f8e7c98373d620832933522ad29d14f (patch)
tree79c22dab921c185c3fb5b3bef32d291627ea01ae /tumblerd
parentad8d6ac59b20ab8ccbb3ce4d56c71d25f2a435b6 (diff)
downloadtumbler-a188f1c30f8e7c98373d620832933522ad29d14f.tar.gz
Try all available thumbnailers before declaring failure
The request thumbnailer array no longer contains one thumbnailer per URI, but the list of available thumbnailers for this URI (after applying the filters of the configuration file), sorted by priority. For a given URI, we browse the thumbnailer list until we succeed in generating a thumbnail. An error signal is only issued if the last thumbnailer has failed. Intermediate errors are only displayed if debug logging is enabled. Closes #50.
Diffstat (limited to 'tumblerd')
-rw-r--r--tumblerd/tumbler-group-scheduler.c48
-rw-r--r--tumblerd/tumbler-lifo-scheduler.c54
-rw-r--r--tumblerd/tumbler-registry.c13
-rw-r--r--tumblerd/tumbler-registry.h2
-rw-r--r--tumblerd/tumbler-scheduler.c36
-rw-r--r--tumblerd/tumbler-scheduler.h12
-rw-r--r--tumblerd/tumbler-service.c4
7 files changed, 113 insertions, 56 deletions
diff --git a/tumblerd/tumbler-group-scheduler.c b/tumblerd/tumbler-group-scheduler.c
index f756f7a..a266542 100644
--- a/tumblerd/tumbler-group-scheduler.c
+++ b/tumblerd/tumbler-group-scheduler.c
@@ -423,7 +423,7 @@ tumbler_group_scheduler_thread (gpointer data,
GList *ready_uris;
GList *cached_uris = NULL;
GList *missing_uris = NULL;
- GList *lp;
+ GList *lp, *lq;
guint n;
gint error_code = 0;
GQuark error_domain = 0;
@@ -550,25 +550,33 @@ tumbler_group_scheduler_thread (gpointer data,
}
tumbler_mutex_unlock (scheduler->mutex);
- /* connect to the error signal of the thumbnailer */
- g_signal_connect (request->thumbnailers[n], "error",
- G_CALLBACK (tumbler_group_scheduler_thumbnailer_error),
- &uri_errors);
-
- /* connect to the ready signal of the thumbnailer */
- g_signal_connect (request->thumbnailers[n], "ready",
- G_CALLBACK (tumbler_group_scheduler_thumbnailer_ready),
- &ready_uris);
-
- /* tell the thumbnailer to generate the thumbnail */
- tumbler_thumbnailer_create (request->thumbnailers[n],
- request->cancellables[n],
- request->infos[n]);
-
- /* disconnect from all signals when we're finished */
- g_signal_handlers_disconnect_matched (request->thumbnailers[n],
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, request);
+ for (lq = request->thumbnailers[n]; lq != NULL; lq = lq->next)
+ {
+ /* forward only the error signal of the last thumbnailer */
+ if (lq->next == NULL)
+ g_signal_connect (lq->data, "error",
+ G_CALLBACK (tumbler_group_scheduler_thumbnailer_error), &uri_errors);
+ else if (tumbler_util_is_debug_logging_enabled (G_LOG_DOMAIN))
+ g_signal_connect (lq->data, "error",
+ G_CALLBACK (tumbler_scheduler_thumberr_debuglog), request);
+
+ /* connect to the ready signal of the thumbnailer */
+ g_signal_connect (lq->data, "ready",
+ G_CALLBACK (tumbler_group_scheduler_thumbnailer_ready), &ready_uris);
+
+ /* cancel lower priority thumbnailers for this uri on ready signal */
+ g_signal_connect_swapped (lq->data, "ready", G_CALLBACK (g_cancellable_cancel),
+ request->cancellables[n]);
+
+ /* tell the thumbnailer to generate the thumbnail */
+ tumbler_thumbnailer_create (lq->data, request->cancellables[n], request->infos[n]);
+
+ /* disconnect from all signals when we're finished */
+ g_signal_handlers_disconnect_by_data (lq->data, &uri_errors);
+ g_signal_handlers_disconnect_by_data (lq->data, &ready_uris);
+ g_signal_handlers_disconnect_by_data (lq->data, request);
+ g_signal_handlers_disconnect_by_data (lq->data, request->cancellables[n]);
+ }
}
tumbler_mutex_lock (scheduler->mutex);
diff --git a/tumblerd/tumbler-lifo-scheduler.c b/tumblerd/tumbler-lifo-scheduler.c
index e19d811..f1ff821 100644
--- a/tumblerd/tumbler-lifo-scheduler.c
+++ b/tumblerd/tumbler-lifo-scheduler.c
@@ -362,7 +362,7 @@ tumbler_lifo_scheduler_thread (gpointer data,
GError *error = NULL;
GList *cached_uris = NULL;
GList *missing_uris = NULL;
- GList *lp;
+ GList *lp, *lq;
guint n;
g_return_if_fail (TUMBLER_IS_LIFO_SCHEDULER (scheduler));
@@ -475,29 +475,35 @@ tumbler_lifo_scheduler_thread (gpointer data,
return;
}
- /* We immediately forward error and ready so that clients rapidly know
- * when individual thumbnails are ready. It's a LIFO for better inter-
- * activity with the clients, so we assume this behaviour to be desired. */
-
- /* connect to the error signal of the thumbnailer */
- g_signal_connect (request->thumbnailers[n], "error",
- G_CALLBACK (tumbler_lifo_scheduler_thumbnailer_error),
- request);
-
- /* connect to the ready signal of the thumbnailer */
- g_signal_connect (request->thumbnailers[n], "ready",
- G_CALLBACK (tumbler_lifo_scheduler_thumbnailer_ready),
- request);
-
- /* tell the thumbnailer to generate the thumbnail */
- tumbler_thumbnailer_create (request->thumbnailers[n],
- request->cancellables[n],
- request->infos[n]);
-
- /* disconnect from all signals when we're finished */
- g_signal_handlers_disconnect_matched (request->thumbnailers[n],
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, request);
+ for (lq = request->thumbnailers[n]; lq != NULL; lq = lq->next)
+ {
+ /* We immediately forward error and ready so that clients rapidly know
+ * when individual thumbnails are ready. It's a LIFO for better inter-
+ * activity with the clients, so we assume this behaviour to be desired. */
+
+ /* forward only the error signal of the last thumbnailer */
+ if (lq->next == NULL)
+ g_signal_connect (lq->data, "error",
+ G_CALLBACK (tumbler_lifo_scheduler_thumbnailer_error), request);
+ else if (tumbler_util_is_debug_logging_enabled (G_LOG_DOMAIN))
+ g_signal_connect (lq->data, "error",
+ G_CALLBACK (tumbler_scheduler_thumberr_debuglog), request);
+
+ /* connect to the ready signal of the thumbnailer */
+ g_signal_connect (lq->data, "ready",
+ G_CALLBACK (tumbler_lifo_scheduler_thumbnailer_ready), request);
+
+ /* cancel lower priority thumbnailers for this uri on ready signal */
+ g_signal_connect_swapped (lq->data, "ready", G_CALLBACK (g_cancellable_cancel),
+ request->cancellables[n]);
+
+ /* tell the thumbnailer to generate the thumbnail */
+ tumbler_thumbnailer_create (lq->data, request->cancellables[n], request->infos[n]);
+
+ /* disconnect from all signals when we're finished */
+ g_signal_handlers_disconnect_by_data (lq->data, request);
+ g_signal_handlers_disconnect_by_data (lq->data, request->cancellables[n]);
+ }
}
/* free list */
diff --git a/tumblerd/tumbler-registry.c b/tumblerd/tumbler-registry.c
index 32cdbfc..6f75654 100644
--- a/tumblerd/tumbler-registry.c
+++ b/tumblerd/tumbler-registry.c
@@ -411,12 +411,12 @@ tumbler_registry_get_thumbnailers (TumblerRegistry *registry)
-TumblerThumbnailer **
+GList **
tumbler_registry_get_thumbnailer_array (TumblerRegistry *registry,
TumblerFileInfo **infos,
guint length)
{
- TumblerThumbnailer **thumbnailers = NULL;
+ GList **thumbnailers = NULL;
gchar *hash_key;
gchar *scheme;
guint n;
@@ -432,7 +432,7 @@ tumbler_registry_get_thumbnailer_array (TumblerRegistry *registry,
tumbler_mutex_lock (registry->mutex);
/* allocate the thumbnailer array */
- thumbnailers = g_new0 (TumblerThumbnailer *, length + 1);
+ thumbnailers = g_new0 (GList *, length + 1);
/* iterate over all URIs */
for (n = 0; n < length; ++n)
@@ -475,11 +475,12 @@ tumbler_registry_get_thumbnailer_array (TumblerRegistry *registry,
}
/* found a usable thumbnailer */
- thumbnailers[n] = g_object_ref (lp->data);
-
- break;
+ thumbnailers[n] = g_list_prepend (thumbnailers[n], g_object_ref (lp->data));
}
+ /* restore thumbnailer priority */
+ thumbnailers[n] = g_list_reverse (thumbnailers[n]);
+
/* cleanup */
g_free (hash_key);
g_free (scheme);
diff --git a/tumblerd/tumbler-registry.h b/tumblerd/tumbler-registry.h
index c58a0e0..9714250 100644
--- a/tumblerd/tumbler-registry.h
+++ b/tumblerd/tumbler-registry.h
@@ -45,7 +45,7 @@ void tumbler_registry_add (TumblerRegistry
void tumbler_registry_remove (TumblerRegistry *registry,
TumblerThumbnailer *thumbnailer);
GList *tumbler_registry_get_thumbnailers (TumblerRegistry *registry) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-TumblerThumbnailer **tumbler_registry_get_thumbnailer_array (TumblerRegistry *registry,
+GList **tumbler_registry_get_thumbnailer_array (TumblerRegistry *registry,
TumblerFileInfo **infos,
guint length) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
void tumbler_registry_update_supported (TumblerRegistry *registry);
diff --git a/tumblerd/tumbler-scheduler.c b/tumblerd/tumbler-scheduler.c
index 2110bc2..8ad820a 100644
--- a/tumblerd/tumbler-scheduler.c
+++ b/tumblerd/tumbler-scheduler.c
@@ -234,7 +234,7 @@ tumbler_scheduler_emit_uri_error (TumblerScheduler *scheduler,
TumblerSchedulerRequest *
tumbler_scheduler_request_new (TumblerFileInfo **infos,
- TumblerThumbnailer **thumbnailers,
+ GList **thumbnailers,
guint length,
const gchar *origin)
{
@@ -335,3 +335,37 @@ tumbler_scheduler_thread_use_lower_priority (void)
sched_setscheduler (0, SCHED_IDLE, &sp);
#endif
}
+
+
+
+void
+tumbler_scheduler_thumberr_debuglog (TumblerThumbnailer *thumbnailer,
+ const gchar *failed_uri,
+ GQuark error_domain,
+ gint error_code,
+ const gchar *message,
+ TumblerSchedulerRequest *request)
+{
+ gchar *text;
+
+ g_return_if_fail (TUMBLER_IS_THUMBNAILER (thumbnailer));
+ g_return_if_fail (failed_uri != NULL);
+ g_return_if_fail (request != NULL);
+ g_return_if_fail (TUMBLER_IS_SCHEDULER (request->scheduler));
+
+ if (error_domain == G_IO_ERROR && error_code == G_IO_ERROR_CANCELLED)
+ return;
+
+ if (error_domain == TUMBLER_ERROR)
+ text = g_strdup (message);
+ else
+ {
+ error_code = TUMBLER_ERROR_OTHER_ERROR_DOMAIN;
+ text = g_strdup_printf ("(domain %s, code %d) %s",
+ g_quark_to_string (error_domain), error_code, message);
+ }
+
+ g_debug ("Failed attempt for job %d, URI '%s': Code %d, message: %s",
+ request->handle, failed_uri, error_code, text);
+ g_free (text);
+}
diff --git a/tumblerd/tumbler-scheduler.h b/tumblerd/tumbler-scheduler.h
index 6423166..a317d66 100644
--- a/tumblerd/tumbler-scheduler.h
+++ b/tumblerd/tumbler-scheduler.h
@@ -81,7 +81,7 @@ void tumbler_scheduler_emit_uri_error (TumblerSchedul
const gchar *uri,
GError *error);
TumblerSchedulerRequest *tumbler_scheduler_request_new (TumblerFileInfo **infos,
- TumblerThumbnailer **thumbnailers,
+ GList **thumbnailers,
guint length,
const gchar *origin);
void tumbler_scheduler_request_free (gpointer data);
@@ -91,9 +91,17 @@ gint tumbler_scheduler_request_compare (gconstpointer
void tumbler_scheduler_thread_use_lower_priority (void);
+/* debug */
+void tumbler_scheduler_thumberr_debuglog (TumblerThumbnailer *thumbnailer,
+ const gchar *failed_uri,
+ GQuark error_domain,
+ gint error_code,
+ const gchar *message,
+ TumblerSchedulerRequest *request);
+
struct _TumblerSchedulerRequest
{
- TumblerThumbnailer **thumbnailers;
+ GList **thumbnailers;
TumblerScheduler *scheduler;
TumblerFileInfo **infos;
GCancellable **cancellables;
diff --git a/tumblerd/tumbler-service.c b/tumblerd/tumbler-service.c
index 8e6fbf1..a60858e 100644
--- a/tumblerd/tumbler-service.c
+++ b/tumblerd/tumbler-service.c
@@ -460,7 +460,7 @@ tumbler_service_scheduler_error (TumblerScheduler *scheduler,
else
{
info->error_code = TUMBLER_ERROR_OTHER_ERROR_DOMAIN;
- info->message = g_strdup_printf ("(%s error, code %d) %s",
+ info->message = g_strdup_printf ("(domain %s, code %d) %s",
g_quark_to_string (error_domain), error_code, message);
}
@@ -716,10 +716,10 @@ tumbler_service_queue_cb (TumblerExportedService *skeleton,
{
TumblerSchedulerRequest *scheduler_request;
TumblerThumbnailFlavor *flavor;
- TumblerThumbnailer **thumbnailers;
TumblerScheduler *scheduler = NULL;
TumblerFileInfo **infos;
TumblerCache *cache;
+ GList **thumbnailers;
GList *iter;
gchar *name;
const gchar *origin;