[folks] Add Backend.is_prepared and make prepare() idempotent.



commit 42612cdf772bc6a03d2f43bbbc3568d1439227c2
Author: Travis Reitter <travis reitter collabora co uk>
Date:   Thu Sep 9 09:24:11 2010 -0700

    Add Backend.is_prepared and make prepare() idempotent.
    
    Fixes bgo#629331.

 NEWS                               |    3 ++
 backends/key-file/kf-backend.vala  |   66 +++++++++++++++++++++++++-----------
 backends/telepathy/tp-backend.vala |   47 +++++++++++++++++++------
 folks/backend.vala                 |   10 +++++
 4 files changed, 95 insertions(+), 31 deletions(-)
---
diff --git a/NEWS b/NEWS
index bb31260..4986937 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ Major changes:
 * Made the folks-import build optional through a configure argument
 * Added support for a â??selfâ?? individual
 * Added support for generating and installing Devhelp format documentation
+* BackendStore.load_backends and the prepare() functions are now idempotent
 
 API changes:
 * Added IMable.normalise_im_address()
@@ -42,6 +43,8 @@ Bugs fixed:
 * Bug 629643 â?? do not fall back to the id if alias is empty
 * Bug 629006 â?? PersonaStore should gracefully handle offline Persona change
   attempts
+* Bug 629331 â?? BackendStore.load_backends and the prepare() functions should
+  be idempotent.
 
 Overview of changes from libfolks 0.1.16 to libfolks 0.1.17
 ===========================================================
diff --git a/backends/key-file/kf-backend.vala b/backends/key-file/kf-backend.vala
index 3da0d23..b36c4f4 100644
--- a/backends/key-file/kf-backend.vala
+++ b/backends/key-file/kf-backend.vala
@@ -31,6 +31,20 @@ using Folks.Backends.Kf;
  */
 public class Folks.Backends.Kf.Backend : Folks.Backend
 {
+  private bool _is_prepared = false;
+
+  /**
+   * Whether this Backend has been prepared.
+   *
+   * See { link Folks.Backend.is_prepared}.
+   *
+   * @since 0.3.0
+   */
+  public override bool is_prepared
+    {
+      get { return this._is_prepared; }
+    }
+
   /**
    * { inheritDoc}
    */
@@ -57,31 +71,43 @@ public class Folks.Backends.Kf.Backend : Folks.Backend
    */
   public override async void prepare () throws GLib.Error
     {
-      File file;
-      string path = Environment.get_variable ("FOLKS_BACKEND_KEY_FILE_PATH");
-      if (path == null)
+      lock (this._is_prepared)
         {
-          file = File.new_for_path (Environment.get_user_data_dir ());
-          file = file.get_child ("folks");
-          file = file.get_child ("relationships.ini");
+          if (!this._is_prepared)
+            {
+              File file;
+              string path = Environment.get_variable (
+                  "FOLKS_BACKEND_KEY_FILE_PATH");
+              if (path == null)
+                {
+                  file = File.new_for_path (Environment.get_user_data_dir ());
+                  file = file.get_child ("folks");
+                  file = file.get_child ("relationships.ini");
 
-          debug ("Using built-in key file '%s' (override with environment " +
-              "variable FOLKS_BACKEND_KEY_FILE_PATH)", file.get_path ());
-        }
-      else
-        {
-          file = File.new_for_path (path);
-          debug ("Using environment variable FOLKS_BACKEND_KEY_FILE_PATH = '%s'"
-              + " to load the key file.", path);
-        }
+                  debug ("Using built-in key file '%s' (override with " +
+                      "environment variable FOLKS_BACKEND_KEY_FILE_PATH)",
+                      file.get_path ());
+                }
+              else
+                {
+                  file = File.new_for_path (path);
+                  debug ("Using environment variable " +
+                      "FOLKS_BACKEND_KEY_FILE_PATH = '%s' to load the key " +
+                      "file.", path);
+                }
 
-      /* Create the PersonaStore for the key file */
-      PersonaStore store = new Kf.PersonaStore (file);
+              /* Create the PersonaStore for the key file */
+              PersonaStore store = new Kf.PersonaStore (file);
 
-      this.persona_stores.insert (store.id, store);
-      store.removed.connect (this.store_removed_cb);
+              this.persona_stores.insert (store.id, store);
+              store.removed.connect (this.store_removed_cb);
 
-      this.persona_store_added (store);
+              this.persona_store_added (store);
+
+              this._is_prepared = true;
+              this.notify_property ("is-prepared");
+            }
+        }
     }
 
   private void store_removed_cb (Folks.PersonaStore store)
diff --git a/backends/telepathy/tp-backend.vala b/backends/telepathy/tp-backend.vala
index d1536f8..edc8df8 100644
--- a/backends/telepathy/tp-backend.vala
+++ b/backends/telepathy/tp-backend.vala
@@ -30,6 +30,7 @@ using Folks.Backends.Tp;
 public class Folks.Backends.Tp.Backend : Folks.Backend
 {
   private AccountManager account_manager;
+  private bool _is_prepared = false;
 
   /**
    * { inheritDoc}
@@ -53,23 +54,47 @@ public class Folks.Backends.Tp.Backend : Folks.Backend
     }
 
   /**
+   * Whether this Backend has been prepared.
+   *
+   * See { link Folks.Backend.is_prepared}.
+   *
+   * @since 0.3.0
+   */
+  public override bool is_prepared
+    {
+      get { return this._is_prepared; }
+    }
+
+  /**
    * { inheritDoc}
    */
   public override async void prepare () throws GLib.Error
     {
-      this.account_manager = AccountManager.dup ();
-      yield this.account_manager.prepare_async (null);
-      this.account_manager.account_enabled.connect (this.account_enabled_cb);
-      this.account_manager.account_validity_changed.connect ((a, valid) =>
+      lock (this._is_prepared)
         {
-          if (valid)
-            this.account_enabled_cb (a);
-        });
+          if (!this._is_prepared)
+            {
+              this.account_manager = AccountManager.dup ();
+              yield this.account_manager.prepare_async (null);
+              this.account_manager.account_enabled.connect (
+                  this.account_enabled_cb);
+              this.account_manager.account_validity_changed.connect (
+                  (a, valid) =>
+                    {
+                      if (valid)
+                        this.account_enabled_cb (a);
+                    });
 
-      GLib.List<unowned Account> accounts = this.account_manager.get_valid_accounts ();
-      foreach (Account account in accounts)
-        {
-          this.account_enabled_cb (account);
+              GLib.List<unowned Account> accounts =
+                  this.account_manager.get_valid_accounts ();
+              foreach (Account account in accounts)
+                {
+                  this.account_enabled_cb (account);
+                }
+
+              this._is_prepared = true;
+              this.notify_property ("is-prepared");
+            }
         }
     }
 
diff --git a/folks/backend.vala b/folks/backend.vala
index 5565b48..696a00c 100644
--- a/folks/backend.vala
+++ b/folks/backend.vala
@@ -35,6 +35,14 @@ using GLib;
 public abstract class Folks.Backend : Object
 {
   /**
+   * Whether { link Backend.prepare} has successfully completed for this
+   * backend.
+   *
+   * @since 0.3.0
+   */
+  public abstract bool is_prepared { get; default = false; }
+
+  /**
    * A unique name for the backend.
    *
    * This will be used to identify the backend, and should also be used as the
@@ -91,6 +99,8 @@ public abstract class Folks.Backend : Object
    *
    * If this function throws an error, the Backend will not be functional.
    *
+   * This function is guaranteed to be idempotent (since version 0.3.0).
+   *
    * @since 0.1.11
    */
   public abstract async void prepare () throws GLib.Error;



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