[folks/folks-0-2] Remove links to personas before they're relinked in the aggregator



commit 7d76d612151e19ede12427dbc8044abc34c94b20
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Sun Nov 7 21:46:09 2010 +0000

    Remove links to personas before they're relinked in the aggregator
    
    If one persona is removed from a non-singleton individual (e.g. because they
    went offline), the other personas in the individual will be relinked into new
    individuals (singleton or not). We previously didn't ensure that the entries
    in the link map corresponding to these personas were removed before the
    personas were relinked which, under certain circumstances (which I haven't
    fully explored), could cause the personas to be relinked to the individual
    which had just been removed. This would cause the individual's persona list
    to grow exponentially, and generally Bad Things to happen.
    
    I could reproduce this situation by logging into two accounts, both of which
    had the other added to their roster. The resulting four personas corresponding
    to the two accounts (2 user personas and 2 normal personas) would be linked
    to form one user individual. Going offline and then online again would trigger
    the bug.
    
    Closes: bgo#633080

 folks/individual-aggregator.vala |   38 +++++++++++++++++++++++++++++++++++---
 1 files changed, 35 insertions(+), 3 deletions(-)
---
diff --git a/folks/individual-aggregator.vala b/folks/individual-aggregator.vala
index c7c0e03..cc79a09 100644
--- a/folks/individual-aggregator.vala
+++ b/folks/individual-aggregator.vala
@@ -484,10 +484,42 @@ public class Folks.IndividualAggregator : Object
 
           /* Build a list of Personas which need relinking. Ensure we don't
            * include any of the Personas which have just been removed. */
-          foreach (unowned Persona p in individual.personas)
+          foreach (unowned Persona persona in individual.personas)
             {
-              if (removed_personas.contains (p) == false)
-                relinked_personas.prepend (p);
+              if (removed_personas.contains (persona) == true)
+                continue;
+
+              relinked_personas.prepend (persona);
+
+              /* Remove links to the persona */
+              this.link_map.remove (persona.iid);
+
+              if (persona.store.trust_level == PersonaStoreTrust.FULL)
+                {
+                  debug ("    Removing links:");
+
+                  /* Remove maps from the Persona's linkable properties to
+                   * Individuals. Add the Individuals to a list of Individuals
+                   * to be removed. */
+                 foreach (string prop_name in persona.linkable_properties)
+                    {
+                     unowned ObjectClass pclass = persona.get_class ();
+                      if (pclass.find_property (prop_name) == null)
+                        {
+                          warning ("Unknown property '%s' in linkable " +
+                              "property list.", prop_name);
+                          continue;
+                        }
+
+                      persona.linkable_property_to_links (prop_name, (l) =>
+                        {
+                          string prop_linking_value = (string) l;
+
+                          debug ("        %s", prop_linking_value);
+                          this.link_map.remove (prop_linking_value);
+                        });
+                    }
+                }
             }
 
           this.individuals.remove (individual.id);



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