Exemplo n.º 1
0
        public static bool LoadFullyIfNeeded(BubbleGroup group, bool sync = false)
        {
            if (@group == null)
            {
                return(false);
            }

            var loadedSomething = false;

            lock (BubbleGroupDatabase.OperationLock)
            {
                var unifiedGroup = @group as UnifiedBubbleGroup;

                var adjustUnifiedGroupUnreadIndicatorIfExists = false;
                var associatedGroups = unifiedGroup != null
                    ? unifiedGroup.Groups.ToList()
                    : new[] { @group }.ToList();
                var associatedPartiallyLoadedGroups = associatedGroups.Where(x => x.PartiallyLoaded).ToList();
                foreach (var partiallyLoadedGroup in associatedPartiallyLoadedGroups)
                {
                    var partiallyLoadedBubblesToRemove = partiallyLoadedGroup.Bubbles.ToList();
                    var rollingBack = false;
TryAgain:
                    try
                    {
                        loadedSomething = true;
                        partiallyLoadedGroup.PartiallyLoaded = false;
                        foreach (var bubble in BubbleGroupDatabase.FetchBubbles(partiallyLoadedGroup).Reverse())
                        {
                            partiallyLoadedGroup.Bubbles.Add(bubble);
                        }
                        foreach (var partiallyLoadedBubbleToRemove in partiallyLoadedBubblesToRemove)
                        {
                            partiallyLoadedGroup.Bubbles.Remove(partiallyLoadedBubbleToRemove);
                        }
                        if (partiallyLoadedGroup.Bubbles.Count < 1)
                        {
                            foreach (var partiallyLoadedBubbleToRemove in partiallyLoadedBubblesToRemove)
                            {
                                partiallyLoadedGroup.Bubbles.Add(partiallyLoadedBubbleToRemove);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Utils.DebugPrint("Failed to fully load partially loaded group " + partiallyLoadedGroup.ID + ": " + ex);
                        if (!rollingBack)
                        {
                            Utils.DebugPrint("Attempting to roll back the last transaction....");
                            BubbleGroupSettingsManager.SetUnreadIndicatorGuid(partiallyLoadedGroup, null, false);
                            adjustUnifiedGroupUnreadIndicatorIfExists = true;
                            rollingBack = true;
                            var lastModifiedIndex = BubbleGroupIndex.GetLastModifiedIndex(partiallyLoadedGroup.ID);
                            if (lastModifiedIndex.HasValue)
                            {
                                try
                                {
                                    BubbleGroupDatabase.RollBackTo(partiallyLoadedGroup, lastModifiedIndex.Value);
                                    goto TryAgain;
                                }
                                catch (Exception ex2)
                                {
                                    Utils.DebugPrint("Failed to rollback: " + ex2);
                                    // fall-through. It's unrecoverable!
                                }
                            }
                            else
                            {
                                // fall-through. It's unrecoverable!
                            }
                        }
                        Utils.DebugPrint("Partially loaded group is dead. Killing and restarting (lost data occurred).");
                        BubbleGroupDatabase.Kill(partiallyLoadedGroup);
                        BubbleGroupSync.RemoveFromSync(partiallyLoadedGroup);
                        BubbleGroupDatabase.AddBubbles(partiallyLoadedGroup,
                                                       partiallyLoadedBubblesToRemove.ToArray());
                    }
                }

                if (unifiedGroup != null && !unifiedGroup.UnifiedGroupLoaded)
                {
                    Populate(unifiedGroup);
                }
                if (unifiedGroup != null && adjustUnifiedGroupUnreadIndicatorIfExists)
                {
                    BubbleGroupSettingsManager.SetUnreadIndicatorGuid(unifiedGroup, null, false);
                }
            }

            if (!sync && loadedSomething)
            {
                Task.Factory.StartNew(() =>
                {
                    var unifiedGroup = @group as UnifiedBubbleGroup;
                    if (unifiedGroup != null)
                    {
                        BubbleQueueManager.Send(unifiedGroup.Groups.Where(x => ServiceManager.IsRunning(x.Service))
                                                .Select(x => x.Service.Information.ServiceName).ToArray());
                    }
                    else if (ServiceManager.IsRunning(@group.Service))
                    {
                        BubbleQueueManager.Send(new[] { @group.Service.Information.ServiceName });
                    }
                    BubbleQueueManager.SetNotQueuedToFailures(@group);
                });
            }

            return(loadedSomething);
        }