summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2018-11-13 12:23:30 +0100
committerCarlos Garnacho <carlosg@gnome.org>2018-11-13 12:23:30 +0100
commit6c5a3fa52fee5779a3a286896f032c50e5b446ff (patch)
tree228b33696d190558c089b0535b81ac7fa3c0afcf
parenteb82efe8dacdca2b283264c52286244a01682e73 (diff)
parentefd69c3629952931e4ec255a494d025eccb9769d (diff)
downloadtracker-6c5a3fa52fee5779a3a286896f032c50e5b446ff.tar.gz
Merge branch 'wip/carlosg/automatic-store-shutdown'
-rw-r--r--src/libtracker-bus/tracker-bus.vala16
-rw-r--r--src/libtracker-miner/tracker-miner-proxy.c68
-rw-r--r--src/libtracker-sparql-backend/tracker-backend.vala18
-rw-r--r--src/tracker-store/tracker-main.vala32
-rw-r--r--src/tracker-store/tracker-store.vala59
-rw-r--r--tests/functional-tests/ipc/test-bus-query.vala2
-rw-r--r--tests/functional-tests/ipc/test-bus-update.vala2
7 files changed, 105 insertions, 92 deletions
diff --git a/src/libtracker-bus/tracker-bus.vala b/src/libtracker-bus/tracker-bus.vala
index 3b971d030..a257c51c8 100644
--- a/src/libtracker-bus/tracker-bus.vala
+++ b/src/libtracker-bus/tracker-bus.vala
@@ -21,7 +21,7 @@ public class Tracker.Bus.Connection : Tracker.Sparql.Connection {
DBusConnection bus;
string dbus_name;
- public Connection (string dbus_name, DBusConnection? dbus_connection) throws Sparql.Error, IOError, DBusError, GLib.Error {
+ public Connection (string dbus_name, DBusConnection? dbus_connection, bool start) throws Sparql.Error, IOError, DBusError, GLib.Error {
this.dbus_name = dbus_name;
if (dbus_connection == null)
@@ -29,14 +29,16 @@ public class Tracker.Bus.Connection : Tracker.Sparql.Connection {
else
bus = dbus_connection;
- debug ("Waiting for service to become available...");
+ if (start) {
+ debug ("Waiting for service to become available...");
- // do not use proxy to work around race condition in GDBus
- // NB#259760
- var msg = new DBusMessage.method_call (dbus_name, Tracker.DBUS_OBJECT_STATUS, Tracker.DBUS_INTERFACE_STATUS, "Wait");
- bus.send_message_with_reply_sync (msg, 0, /* timeout */ int.MAX, null).to_gerror ();
+ // do not use proxy to work around race condition in GDBus
+ // NB#259760
+ var msg = new DBusMessage.method_call (dbus_name, Tracker.DBUS_OBJECT_STATUS, Tracker.DBUS_INTERFACE_STATUS, "Wait");
+ bus.send_message_with_reply_sync (msg, 0, /* timeout */ int.MAX, null).to_gerror ();
- debug ("Service is ready");
+ debug ("Service is ready");
+ }
// ensure that error domain is registered with GDBus
new Sparql.Error.INTERNAL ("");
diff --git a/src/libtracker-miner/tracker-miner-proxy.c b/src/libtracker-miner/tracker-miner-proxy.c
index 0e47395aa..465d6103c 100644
--- a/src/libtracker-miner/tracker-miner-proxy.c
+++ b/src/libtracker-miner/tracker-miner-proxy.c
@@ -51,9 +51,7 @@ typedef struct {
GDBusNodeInfo *introspection_data;
gchar *dbus_path;
guint registration_id;
- guint watch_name_id;
GHashTable *pauses;
- gint availability_cookie;
} TrackerMinerProxyPrivate;
typedef struct {
@@ -222,10 +220,6 @@ tracker_miner_proxy_finalize (GObject *object)
g_free (priv->dbus_path);
g_hash_table_unref (priv->pauses);
- if (priv->watch_name_id != 0) {
- g_bus_unwatch_name (priv->watch_name_id);
- }
-
if (priv->registration_id != 0) {
g_dbus_connection_unregister_object (priv->d_connection,
priv->registration_id);
@@ -732,55 +726,6 @@ miner_progress_cb (TrackerMiner *miner,
emit_dbus_signal (proxy, "Progress", variant);
}
-static void
-on_tracker_store_appeared (GDBusConnection *connection,
- const gchar *name,
- const gchar *name_owner,
- gpointer user_data)
-
-{
- TrackerMinerProxy *proxy = user_data;
- TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy);
-
- g_debug ("Miner:'%s' noticed store availability has changed to AVAILABLE",
- priv->dbus_path);
-
- if (priv->availability_cookie != 0) {
- g_hash_table_remove (priv->pauses,
- GINT_TO_POINTER (priv->availability_cookie));
- sync_miner_pause_state (proxy);
- priv->availability_cookie = 0;
- }
-}
-
-static void
-on_tracker_store_disappeared (GDBusConnection *connection,
- const gchar *name,
- gpointer user_data)
-{
- TrackerMinerProxy *proxy = user_data;
- TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy);
-
- g_debug ("Miner:'%s' noticed store availability has changed to UNAVAILABLE",
- priv->dbus_path);
-
- if (priv->availability_cookie == 0) {
- GError *error = NULL;
- gint cookie_id;
-
- cookie_id = pause_miner (proxy, NULL,
- _("Data store is not available"),
- NULL, &error);
-
- if (error) {
- g_warning ("Could not pause, %s", error->message);
- g_error_free (error);
- } else {
- priv->availability_cookie = cookie_id;
- }
- }
-}
-
static gboolean
tracker_miner_proxy_initable_init (GInitable *initable,
GCancellable *cancellable,
@@ -790,7 +735,6 @@ tracker_miner_proxy_initable_init (GInitable *initable,
TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy);
GError *inner_error = NULL;
TrackerDomainOntology *domain_ontology;
- gchar *store_name;
GDBusInterfaceVTable interface_vtable = {
handle_method_call,
handle_get_property,
@@ -824,18 +768,6 @@ tracker_miner_proxy_initable_init (GInitable *initable,
return FALSE;
}
- store_name = tracker_domain_ontology_get_domain (domain_ontology, "Tracker1");
-
- priv->watch_name_id =
- g_bus_watch_name_on_connection (priv->d_connection,
- store_name,
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- on_tracker_store_appeared,
- on_tracker_store_disappeared,
- proxy,
- NULL);
- g_free (store_name);
-
g_signal_connect (priv->miner, "started",
G_CALLBACK (miner_started_cb), proxy);
g_signal_connect (priv->miner, "stopped",
diff --git a/src/libtracker-sparql-backend/tracker-backend.vala b/src/libtracker-sparql-backend/tracker-backend.vala
index d99ceb291..db822dc51 100644
--- a/src/libtracker-sparql-backend/tracker-backend.vala
+++ b/src/libtracker-sparql-backend/tracker-backend.vala
@@ -203,12 +203,22 @@ class Tracker.Sparql.Backend : Connection {
switch (backend) {
case Backend.AUTO:
- bus = new Tracker.Bus.Connection (domain_ontology.get_domain ("Tracker1"), global_dbus_connection);
+ bool direct_failed = false;
try {
direct = create_readonly_direct ();
- } catch (GLib.Error e) {
- warning ("Falling back to bus backend, the direct backend failed to initialize: " + e.message);
+ } catch (DBInterfaceError e) {
+ direct_failed = true;
+ }
+
+ bus = new Tracker.Bus.Connection (domain_ontology.get_domain ("Tracker1"), global_dbus_connection, direct_failed);
+
+ if (direct_failed) {
+ try {
+ direct = create_readonly_direct ();
+ } catch (DBInterfaceError e) {
+ warning ("Falling back to bus backend, the direct backend failed to initialize: " + e.message);
+ }
}
break;
@@ -218,7 +228,7 @@ class Tracker.Sparql.Backend : Connection {
break;
case Backend.BUS:
- bus = new Tracker.Bus.Connection (domain_ontology.get_domain ("Tracker1"), global_dbus_connection);
+ bus = new Tracker.Bus.Connection (domain_ontology.get_domain ("Tracker1"), global_dbus_connection, false);
break;
default:
diff --git a/src/tracker-store/tracker-main.vala b/src/tracker-store/tracker-main.vala
index 478076278..1e8d1ddd2 100644
--- a/src/tracker-store/tracker-main.vala
+++ b/src/tracker-store/tracker-main.vala
@@ -37,6 +37,7 @@ License which can be viewed at:
static MainLoop main_loop;
static string log_filename;
+ static uint shutdown_timeout_id;
static bool shutdown;
static Tracker.Direct.Connection connection;
@@ -52,11 +53,13 @@ License which can be viewed at:
static File data_location;
static File ontology_location;
static string domain;
+ static bool disable_shutdown;
const OptionEntry entries[] = {
/* Daemon options */
{ "version", 'V', 0, OptionArg.NONE, ref version, N_("Displays version information"), null },
{ "verbosity", 'v', 0, OptionArg.INT, ref verbosity, N_("Logging, 0 = errors only, 1 = minimal, 2 = detailed and 3 = debug (default = 0)"), null },
+ { "disable-shutdown", 's', 0, OptionArg.NONE, ref disable_shutdown, N_("Disable automatic shutdown"), null },
/* Indexer options */
{ "force-reindex", 'r', 0, OptionArg.NONE, ref force_reindex, N_("Force a re-index of all content"), null },
@@ -180,6 +183,33 @@ License which can be viewed at:
return connection;
}
+ private static bool shutdown_timeout () {
+ message ("Store shutting down after timeout");
+ do_shutdown ();
+ return GLib.Source.REMOVE;
+ }
+
+ private static void idle_cb () {
+ /* Do not perform shutdown in case of exotic buses */
+ if (Tracker.IPC.bus () != GLib.BusType.SESSION)
+ return;
+ if (shutdown_timeout_id != 0)
+ return;
+ if (disable_shutdown)
+ return;
+
+ message ("Store is idle, setting shutdown timeout");
+ shutdown_timeout_id = GLib.Timeout.add_seconds (30, shutdown_timeout);
+ }
+
+ private static void busy_cb () {
+ if (shutdown_timeout_id == 0)
+ return;
+ message ("Store is busy, removing shutdown timeout");
+ GLib.Source.remove (shutdown_timeout_id);
+ shutdown_timeout_id = 0;
+ }
+
static int main (string[] args) {
Intl.setlocale (LocaleCategory.ALL, "");
@@ -265,7 +295,7 @@ License which can be viewed at:
var notifier = Tracker.DBus.register_notifier ();
- Tracker.Store.init (config);
+ Tracker.Store.init (config, idle_cb, busy_cb);
/* Make Tracker available for introspection */
if (!Tracker.DBus.register_objects ()) {
diff --git a/src/tracker-store/tracker-store.vala b/src/tracker-store/tracker-store.vala
index 03cc8078a..f7b03a601 100644
--- a/src/tracker-store/tracker-store.vala
+++ b/src/tracker-store/tracker-store.vala
@@ -39,6 +39,11 @@ public class Tracker.Store {
public delegate void SparqlQueryInThread (Sparql.Cursor cursor) throws Error;
+ public delegate void StateCallback ();
+ static unowned StateCallback idle_cb;
+ static unowned StateCallback busy_cb;
+ static bool busy;
+
class CursorTask {
public Sparql.Cursor cursor;
public unowned SourceFunc callback;
@@ -61,11 +66,12 @@ public class Tracker.Store {
Idle.add (() => {
task.callback ();
+ update_state ();
return false;
});
}
- public static void init (Tracker.Config config_p) {
+ public static void init (Tracker.Config config_p, StateCallback idle, StateCallback busy) {
string max_task_time_env = Environment.get_variable ("TRACKER_STORE_MAX_TASK_TIME");
if (max_task_time_env != null) {
max_task_time = int.parse (max_task_time_env);
@@ -88,6 +94,9 @@ public class Tracker.Store {
ThreadPool.set_max_unused_threads (2);
config = config_p;
+ idle_cb = idle;
+ busy_cb = busy;
+ idle_cb ();
}
public static void shutdown () {
@@ -158,30 +167,41 @@ public class Tracker.Store {
// Ignore harmless error
}
+ update_state ();
+
yield;
if (task.error != null)
throw task.error;
}
+ private static void pre_update () {
+ n_updates++;
+ update_state ();
+ ensure_signal_timeout ();
+ }
+
+ private static void post_update () {
+ n_updates--;
+ update_state ();
+ }
+
public static async void sparql_update (Tracker.Direct.Connection conn, string sparql, int priority, string client_id) throws Error {
if (!active)
throw new Sparql.Error.UNSUPPORTED ("Store is not active");
- n_updates++;
- ensure_signal_timeout ();
+ pre_update ();
var cancellable = create_cancellable (client_id);
yield conn.update_async (sparql, priority, cancellable);
- n_updates--;
+ post_update ();
}
public static async Variant sparql_update_blank (Tracker.Direct.Connection conn, string sparql, int priority, string client_id) throws Error {
if (!active)
throw new Sparql.Error.UNSUPPORTED ("Store is not active");
- n_updates++;
- ensure_signal_timeout ();
+ pre_update ();
var cancellable = create_cancellable (client_id);
var nodes = yield conn.update_blank_async (sparql, priority, cancellable);
- n_updates--;
+ post_update ();
return nodes;
}
@@ -189,11 +209,10 @@ public class Tracker.Store {
public static async void queue_turtle_import (Tracker.Direct.Connection conn, File file, string client_id) throws Error {
if (!active)
throw new Sparql.Error.UNSUPPORTED ("Store is not active");
- n_updates++;
- ensure_signal_timeout ();
+ pre_update ();
var cancellable = create_cancellable (client_id);
yield conn.load_async (file, cancellable);
- n_updates--;
+ post_update ();
}
public static void unreg_batches (string client_id) {
@@ -202,6 +221,7 @@ public class Tracker.Store {
if (cancellable != null) {
cancellable.cancel ();
client_cancellables.remove (client_id);
+ update_state ();
}
}
@@ -216,10 +236,29 @@ public class Tracker.Store {
Tracker.Store.active = true;
}
+ private static void update_state () {
+ bool cur_busy;
+
+ cur_busy = (!Tracker.Store.active || /* Keep busy while paused */
+ n_updates != 0 || /* There are updates */
+ cursor_pool.unprocessed () > 0 || /* Select cursor pool is busy */
+ cursor_pool.get_num_threads () > 0);
+
+ if (busy == cur_busy)
+ return;
+
+ busy = cur_busy;
+ if (busy)
+ busy_cb ();
+ else
+ idle_cb ();
+ }
+
private static void on_statements_committed () {
Tracker.Events.transact ();
Tracker.Writeback.transact ();
check_graph_updated_signal ();
+ update_state ();
}
private static void on_statements_rolled_back () {
diff --git a/tests/functional-tests/ipc/test-bus-query.vala b/tests/functional-tests/ipc/test-bus-query.vala
index 997dc9e7c..4e51a2b07 100644
--- a/tests/functional-tests/ipc/test-bus-query.vala
+++ b/tests/functional-tests/ipc/test-bus-query.vala
@@ -5,7 +5,7 @@ int
main( string[] args )
{
try {
- TestApp app = new TestApp (new Tracker.Bus.Connection ("org.freedesktop.Tracker1", null));
+ TestApp app = new TestApp (new Tracker.Bus.Connection ("org.freedesktop.Tracker1", null, true));
return app.run ();
} catch (GLib.Error e) {
diff --git a/tests/functional-tests/ipc/test-bus-update.vala b/tests/functional-tests/ipc/test-bus-update.vala
index 997dc9e7c..4e51a2b07 100644
--- a/tests/functional-tests/ipc/test-bus-update.vala
+++ b/tests/functional-tests/ipc/test-bus-update.vala
@@ -5,7 +5,7 @@ int
main( string[] args )
{
try {
- TestApp app = new TestApp (new Tracker.Bus.Connection ("org.freedesktop.Tracker1", null));
+ TestApp app = new TestApp (new Tracker.Bus.Connection ("org.freedesktop.Tracker1", null, true));
return app.run ();
} catch (GLib.Error e) {