[gnome-boxes] os-database: Load database asynchronously
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes] os-database: Load database asynchronously
- Date: Mon, 19 Nov 2012 17:27:00 +0000 (UTC)
commit eafcdfdded36a8e88eebfaf02fcc310babbd9ba4
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date: Thu Nov 1 18:29:47 2012 +0200
os-database: Load database asynchronously
Load database in a separate thread so the rest of the Application
(especially the UI) can load faster.
In my limited testing, I saw a visible difference in load time.
Christophe did a more systematic analysis and found out it takes about
300ms with a hot cache on his machine to load the DB.
https://bugzilla.gnome.org/show_bug.cgi?id=687357
src/installer-media.vala | 6 +++---
src/media-manager.vala | 4 ++--
src/os-database.vala | 37 +++++++++++++++++++++++++++++++------
3 files changed, 36 insertions(+), 11 deletions(-)
---
diff --git a/src/installer-media.vala b/src/installer-media.vala
index 9973753..fde8cc0 100644
--- a/src/installer-media.vala
+++ b/src/installer-media.vala
@@ -55,7 +55,7 @@ private class Boxes.InstallerMedia : GLib.Object {
var device = yield get_device_from_path (path, media_manager.client, cancellable);
if (device != null)
- get_media_info_from_device (device, media_manager.os_db);
+ yield get_media_info_from_device (device, media_manager.os_db);
else {
from_image = true;
os = yield media_manager.os_db.guess_os_from_install_media (device_file, out os_media, cancellable);
@@ -133,7 +133,7 @@ private class Boxes.InstallerMedia : GLib.Object {
return client.query_by_device_file (device_file);
}
- private void get_media_info_from_device (GUdev.Device device, OSDatabase os_db) throws OSDatabaseError {
+ private async void get_media_info_from_device (GUdev.Device device, OSDatabase os_db) throws OSDatabaseError {
if (!device.get_property_as_boolean ("OSINFO_BOOTABLE"))
throw new OSDatabaseError.NON_BOOTABLE ("Media %s is not bootable.", device_file);
@@ -142,7 +142,7 @@ private class Boxes.InstallerMedia : GLib.Object {
var os_id = device.get_property ("OSINFO_INSTALLER") ?? device.get_property ("OSINFO_LIVE");
if (os_id != null) {
- os = os_db.get_os_by_id (os_id);
+ os = yield os_db.get_os_by_id (os_id);
var media_id = device.get_property ("OSINFO_MEDIA");
if (media_id != null)
diff --git a/src/media-manager.vala b/src/media-manager.vala
index 08c56ba..601ed4c 100644
--- a/src/media-manager.vala
+++ b/src/media-manager.vala
@@ -16,7 +16,7 @@ private class Boxes.MediaManager : Object {
public MediaManager () {
client = new GUdev.Client ({"block"});
os_db = new OSDatabase ();
- os_db.load ();
+ os_db.load.begin ();
try {
connection = Sparql.Connection.get ();
} catch (GLib.Error error) {
@@ -94,7 +94,7 @@ private class Boxes.MediaManager : Object {
if (label == null || os_id == null || media_id == null)
return yield create_installer_media_for_path (path, null);
- var os = os_db.get_os_by_id (os_id);
+ var os = yield os_db.get_os_by_id (os_id);
var os_media = os_db.get_media_by_id (os, media_id);
var resources = os_db.get_resources_for_os (os, os_media.architecture);
var media = new InstallerMedia.from_iso_info (path, label, os, os_media, resources);
diff --git a/src/os-database.vala b/src/os-database.vala
index 54d1fad..18a9f97 100644
--- a/src/os-database.vala
+++ b/src/os-database.vala
@@ -18,6 +18,10 @@ private class Boxes.OSDatabase : GLib.Object {
private Db? db;
+ private bool db_loading;
+
+ private signal void db_loaded ();
+
private static Resources get_default_resources () {
var resources = new Resources ("whatever", "x86_64");
@@ -28,19 +32,22 @@ private class Boxes.OSDatabase : GLib.Object {
return resources;
}
- public void load () {
+ public async void load () {
+ db_loading = true;
var loader = new Loader ();
try {
- loader.process_default_path ();
+ yield run_in_thread (() => { loader.process_default_path (); });
} catch (GLib.Error e) {
warning ("Error loading default libosinfo database: %s", e.message);
}
try {
- loader.process_path (get_logos_db ()); // Load our custom database
+ yield run_in_thread (() => { loader.process_path (get_logos_db ()); }); // Load our custom database
} catch (GLib.Error e) {
warning ("Error loading GNOME Boxes libosinfo database: %s", e.message);
}
db = loader.get_db ();
+ db_loading = false;
+ db_loaded ();
}
public async Os? guess_os_from_install_media (string media_path,
@@ -48,7 +55,7 @@ private class Boxes.OSDatabase : GLib.Object {
Cancellable? cancellable) throws GLib.Error {
os_media = null;
- if (db == null)
+ if (!yield ensure_db_loaded ())
return null;
var media = yield Media.create_from_location_async (media_path, Priority.DEFAULT, cancellable);
@@ -56,8 +63,8 @@ private class Boxes.OSDatabase : GLib.Object {
return db.guess_os_from_media (media, out os_media);
}
- public Os get_os_by_id (string id) throws OSDatabaseError {
- if (db == null)
+ public async Os get_os_by_id (string id) throws OSDatabaseError {
+ if (!yield ensure_db_loaded ())
throw new OSDatabaseError.UNKNOWN_OS_ID ("Unknown OS ID '%s'", id);
var os = db.get_os (id);
@@ -142,4 +149,22 @@ private class Boxes.OSDatabase : GLib.Object {
// (minimum/recommended) of each architecture for each OS.
return filtered.get_nth (0) as Resources;
}
+
+ private async bool ensure_db_loaded () {
+ if (db != null)
+ return true;
+
+ if (db_loading) { // Wait for the DB to load..
+ ulong db_loaded_id = 0;
+
+ db_loaded_id = db_loaded.connect (() => {
+ ensure_db_loaded.callback ();
+ disconnect (db_loaded_id);
+ });
+
+ yield;
+ }
+
+ return (db != null);
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]