[folks] Split setup of Backends out into a Backend.prepare() method



commit 602d4fe8ae8b1dbbc03a32843eee432ba569a103
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Wed Jun 30 14:33:54 2010 +0100

    Split setup of Backends out into a Backend.prepare() method

 backends/telepathy/tp-backend.vala |    6 ++----
 folks/backend.vala                 |   32 ++++++++++++++++++++++++++++++++
 folks/individual-aggregator.vala   |   13 +++++++++++++
 3 files changed, 47 insertions(+), 4 deletions(-)
---
diff --git a/backends/telepathy/tp-backend.vala b/backends/telepathy/tp-backend.vala
index 34f8a3a..016ec2b 100644
--- a/backends/telepathy/tp-backend.vala
+++ b/backends/telepathy/tp-backend.vala
@@ -47,17 +47,15 @@ public class Folks.Backends.Tp.Backend : Folks.Backend
   /**
    * { inheritDoc}
    */
-  public Backend () throws GLib.Error
+  public Backend ()
     {
       Object (name: "telepathy");
 
       this.persona_stores = new HashTable<string, PersonaStore> (str_hash,
           str_equal);
-
-      this.setup_account_manager ();
     }
 
-  private async void setup_account_manager () throws GLib.Error
+  public override async void prepare () throws GLib.Error
     {
       this.account_manager = AccountManager.dup ();
       yield this.account_manager.prepare_async (null);
diff --git a/folks/backend.vala b/folks/backend.vala
index a2d49da..933c773 100644
--- a/folks/backend.vala
+++ b/folks/backend.vala
@@ -25,6 +25,13 @@ using Folks;
  * A single backend to libfolks, such as Telepathy or evolution-data-server.
  * Each backend provides { link Persona}s which are aggregated to form
  * { link Individual}s.
+ *
+ * After creating a Backend instance, you must connect to the
+ * { link Backend.persona_store_added} and
+ * { link Backend.persona_store_removed} signals, //then// call
+ * { link Backend.prepare}, otherwise a race condition may occur between
+ * emission of { link Backend.persona_store_added} and your code connecting to
+ * it.
  */
 public abstract class Folks.Backend : Object
 {
@@ -34,6 +41,9 @@ public abstract class Folks.Backend : Object
    * This will be used to identify the backend, and should also be used as the
    * { link PersonaStore.type_id} of the { link PersonaStore}s used by the
    * backend.
+   *
+   * This is guaranteed to always be available; even before
+   * { link Backend.prepare} is called.
    */
   public abstract string name { get; protected set; }
 
@@ -51,6 +61,9 @@ public abstract class Folks.Backend : Object
   /**
    * Emitted when a { link PersonaStore} is added to the backend.
    *
+   * This will not be emitted until after { link Backend.prepare} has been
+   * called.
+   *
    * @param store the { link PersonaStore}
    */
   public abstract signal void persona_store_added (PersonaStore store);
@@ -58,7 +71,26 @@ public abstract class Folks.Backend : Object
   /**
    * Emitted when a { link PersonaStore} is removed from the backend.
    *
+   * This will not be emitted until after { link Backend.prepare} has been
+   * called.
+   *
    * @param store the { link PersonaStore}
    */
   public abstract signal void persona_store_removed (PersonaStore store);
+
+  /**
+   * Prepare the Backend for use.
+   *
+   * This connects the Backend to whichever backend-specific services it
+   * requires, and causes it to create its { link PersonaStore}s. This should be
+   * called //after// connecting to the { link Backend.persona_store_added} and
+   * { link Backend.persona_store_removed} signals, or a race condition could
+   * occur, with the signals being emitted before your code has connected to
+   * them, and { link PersonaStore}s getting "lost" as a result.
+   *
+   * This is normally handled transparently by the { link IndividualAggregator}.
+   *
+   * If this function throws an error, the Backend will not be functional.
+   */
+  public abstract async void prepare () throws GLib.Error;
 }
diff --git a/folks/individual-aggregator.vala b/folks/individual-aggregator.vala
index f1f523c..0b2fca9 100644
--- a/folks/individual-aggregator.vala
+++ b/folks/individual-aggregator.vala
@@ -107,6 +107,19 @@ public class Folks.IndividualAggregator : Object
       backend.persona_store_added.connect (this.backend_persona_store_added_cb);
       backend.persona_store_removed.connect (
           this.backend_persona_store_removed_cb);
+
+      backend.prepare.begin ((obj, result) =>
+        {
+          try
+            {
+              backend.prepare.end (result);
+            }
+          catch (GLib.Error e)
+            {
+              warning ("Error preparing Backend '%s': %s", backend.name,
+                  e.message);
+            }
+        });
     }
 
   private void backend_persona_store_added_cb (Backend backend,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]