Exemplo n.º 1
0
        private static IEnumerable <bool?> QueuedBubblesIterator(string serviceName, bool hourLimitation = false,
                                                                 bool removeCurrentlySendingBubbles      = false)
        {
            lock (_dbLock)
            {
                var       currentTime   = Time.GetNowUnixTimestamp();
                const int SecondsInHour = 3600;
                using (var db = new SqlDatabase <Entry>(Location))
                {
                    foreach (var possibleBubble in db.Store.Where(x => serviceName == x.ServiceName))
                    {
                        if (hourLimitation && possibleBubble.Time <= currentTime - SecondsInHour)
                        {
                            continue;
                        }

                        foreach (var bubbleGroup in BubbleGroupManager.BubbleGroupsNonUnified)
                        {
                            if (bubbleGroup.PartiallyLoaded)
                            {
                                continue;
                            }

                            foreach (var bubble in bubbleGroup)
                            {
                                if (bubble.Status != Bubble.BubbleStatus.Waiting)
                                {
                                    continue;
                                }

                                if (removeCurrentlySendingBubbles && InsertBubble.IsSending(bubble.ID))
                                {
                                    continue;
                                }

                                if (possibleBubble.Guid == bubble.ID)
                                {
                                    yield return(true);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        public static Task <List <Receipt> > Send(string[] serviceNames, bool scheduled = false)
        {
            return(Task <List <Receipt> > .Factory.StartNew(() =>
            {
                //PROCESS:  1) find all bubbles under serviceNames in db
                //          2) relate db entries to bubbles loaded into memory by Disa
                //          3) parallel send bubbles based respective to service
                //          4) delete all successful bubbles out of db

                lock (_sendLock)
                {
                    var possibleBubblesFromDatabase = new List <Entry>();

                    lock (_dbLock)
                    {
                        using (var db = new SqlDatabase <Entry>(Location))
                        {
                            foreach (var possibleBubble in db.Store.Where(x => serviceNames.Contains(x.ServiceName)).Reverse())
                            {
                                if (!InsertBubble.IsSending(possibleBubble.Guid))
                                {
                                    possibleBubblesFromDatabase.Add(possibleBubble);
                                }
                            }
                        }
                    }

                    var possibleBubblesInDisa = new List <Tuple <Entry, VisualBubble> >();
                    foreach (var bubbleGroup in BubbleGroupManager.BubbleGroupsNonUnified)
                    {
                        if (bubbleGroup.PartiallyLoaded)
                        {
                            continue;
                        }

                        foreach (var bubble in bubbleGroup)
                        {
                            if (bubble.Status != Bubble.BubbleStatus.Waiting)
                            {
                                continue;
                            }

                            var possibleBubbleFromDatabase = possibleBubblesFromDatabase.FirstOrDefault(x => x.Guid == bubble.ID);
                            if (possibleBubbleFromDatabase != null)
                            {
                                possibleBubblesInDisa.Add(new Tuple <Entry, VisualBubble>(possibleBubbleFromDatabase, bubble));
                            }
                        }
                    }

                    var sent = new List <Tuple <Entry, bool> >();

                    var possibleBubblesInDisaByService = possibleBubblesInDisa.GroupBy(x => x.Item1.ServiceName);
                    Parallel.ForEach(possibleBubblesInDisaByService, possibleBubblesInService =>
                    {
                        var failed = false;
                        foreach (var possibleBubble in possibleBubblesInService)
                        {
                            if (failed)
                            {
                                sent.Add(new Tuple <Entry, bool>(possibleBubble.Item1, false));
                                continue;
                            }

                            Utils.DebugPrint(">>>>>>>>>>> Sending queued bubble on "
                                             + possibleBubble.Item2.Service.Information.ServiceName + "!");

                            var sendBubbleTask = BubbleManager.Send(possibleBubble.Item2, true);
                            sendBubbleTask.Wait();
                            if (sendBubbleTask.Result)
                            {
                                Utils.DebugPrint(">>>>>>>>> Successfully sent queued bubble on " +
                                                 possibleBubble.Item2.Service.Information.ServiceName + "!");
                                sent.Add(new Tuple <Entry, bool>(possibleBubble.Item1, true));
                                lock (_dbLock)
                                {
                                    using (var db = new SqlDatabase <Entry>(Location))
                                    {
                                        db.Remove(possibleBubble.Item1);
                                    }
                                }
                                Utils.Delay(100).Wait();
                            }
                            else
                            {
                                Utils.DebugPrint(">>>>>>>>> Failed to send queued bubble on " +
                                                 possibleBubble.Item2.Service.Information.ServiceName + "!");
                                sent.Add(new Tuple <Entry, bool>(possibleBubble.Item1, false));
                                failed = true; // fail the entire chain for this service from here on out so messages aren't sent out of order
                            }
                        }
                    });

                    SanityCheckup();

                    var receipts = sent.Select(x => new Receipt(x.Item1.Guid, x.Item2)).ToList();

                    if (!scheduled)
                    {
                        if (receipts.FirstOrDefault(x => !x.Success) != null)
                        {
                            ScheduleReSend(serviceNames);
                        }
                        else
                        {
                            var needToSendAgain = serviceNames.Where(x => BubbleQueueManager.HasQueuedBubbles(x, true, true)).ToArray();
                            if (needToSendAgain.Any())
                            {
                                Send(needToSendAgain);
                            }
                        }
                    }

                    return receipts;
                }
            }));
        }