private void HandleFailedNotification(int identifier, byte status)
        {
            int failedNotificationIndex         = -1;
            SentNotification failedNotification = null;

            //Try and find the failed notification in our sent list
            for (int i = 0; i < sentNotifications.Count; i++)
            {
                var n = sentNotifications[i];

                if (n.Identifier.Equals(identifier))
                {
                    failedNotificationIndex = i;
                    failedNotification      = n;
                    break;
                }
            }

            //Don't bother doing anything unless we know what failed
            if (failedNotification != null && failedNotificationIndex > -1)
            {
                Interlocked.Decrement(ref PendingNotificationsResult);
                //Anything before the failed message must have sent OK
                // so let's expedite the success status Success for all those before the failed one
                if (failedNotificationIndex > 0)
                {
                    for (int i = 0; i < failedNotificationIndex; i++)
                    {
                        this.Events.RaiseNotificationSent(sentNotifications[i].Notification);
                    }
                }

                //The notification that failed needs to have a failure event raised
                // we don't requeue it because apple told us it failed for real
                this.Events.RaiseNotificationSendFailure(failedNotification.Notification,
                                                         new NotificationFailureException(status, failedNotification.Notification));

                // finally, raise failure for anything after the index of this failed one
                // in the sent list, since we may have sent them but apple will have disregarded
                // anything after the failed one and not told us about it
                if (failedNotificationIndex < sentNotifications.Count - 1)
                {
                    //Requeue the failed notification since we're not sure it's a bad
                    // notification, just that it was sent after a bad one was
                    for (int i = failedNotificationIndex + 1; i <= sentNotifications.Count - 1; i++)
                    {
                        Interlocked.Decrement(ref PendingNotificationsResult);
                        this.QueueNotification(sentNotifications[i].Notification, false);
                    }
                }

                //Now clear out the sent list since we processed them all manually above
                sentNotifications.Clear();
            }
        }
Exemple #2
0
        private void HandleFailedNotification(int identifier, byte status)
        {
            int index = this.sentNotifications.FindIndex((Predicate <SentNotification>)(n => n.Identifier == identifier));

            if (index < 0)
            {
                return;
            }
            Log.Info("Failed Notification: {0}", (object)identifier);
            if (index > 0)
            {
                this.sentNotifications.GetRange(0, index).ForEach((Action <SentNotification>)(n =>
                {
                    Interlocked.Decrement(ref this.trackedNotificationCount);
                    if (n.Callback == null)
                    {
                        return;
                    }
                    n.Callback((object)this, new SendNotificationResult((INotification)n.Notification, false, (Exception)null));
                }));
                this.sentNotifications.RemoveRange(0, index);
            }
            SentNotification failedNotification = this.sentNotifications[0];

            Interlocked.Decrement(ref this.trackedNotificationCount);
            if (failedNotification.Callback != null)
            {
                failedNotification.Callback((object)this, new SendNotificationResult((INotification)failedNotification.Notification, false, (Exception) new NotificationFailureException((int)status, failedNotification.Notification)));
            }
            this.sentNotifications.RemoveAt(0);
            this.sentNotifications.Reverse();
            this.sentNotifications.ForEach((Action <SentNotification>)(n =>
            {
                Interlocked.Decrement(ref this.trackedNotificationCount);
                if (failedNotification.Callback == null)
                {
                    return;
                }
                failedNotification.Callback((object)this, new SendNotificationResult((INotification)n.Notification, true, new Exception("Sent after previously failed Notification."))
                {
                    CountsAsRequeue = false
                });
            }));
            this.sentNotifications.Clear();
        }
Exemple #3
0
        void Reader()
        {
            try
            {
                var result = networkStream.BeginRead(readBuffer, 0, 6, new AsyncCallback((asyncResult) =>
                {
                    lock (sentLock)
                    {
                        try
                        {
                            var bytesRead = networkStream.EndRead(asyncResult);

                            if (bytesRead > 0)
                            {
                                //We now expect apple to close the connection on us anyway, so let's try and close things
                                // up here as well to get a head start
                                //Hopefully this way we have less messages written to the stream that we have to requeue
                                try { stream.Close(); stream.Dispose(); }
                                catch { }

                                try { client.Close(); stream.Dispose(); }
                                catch { }

                                //Get the enhanced format response
                                // byte 0 is always '1', byte 1 is the status, bytes 2,3,4,5 are the identifier of the notification
                                var status     = readBuffer[1];
                                var identifier = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(readBuffer, 2));

                                int failedNotificationIndex         = -1;
                                SentNotification failedNotification = null;

                                //Try and find the failed notification in our sent list
                                for (int i = 0; i < sentNotifications.Count; i++)
                                {
                                    var n = sentNotifications[i];

                                    if (n.Identifier.Equals(identifier))
                                    {
                                        failedNotificationIndex = i;
                                        failedNotification      = n;
                                        break;
                                    }
                                }

                                //Don't bother doing anything unless we know what failed
                                if (failedNotification != null && failedNotificationIndex > -1)
                                {
                                    //Anything before the failed message must have sent OK
                                    // so let's expedite the success status Success for all those before the failed one
                                    if (failedNotificationIndex > 0)
                                    {
                                        for (int i = 0; i < failedNotificationIndex; i++)
                                        {
                                            this.Events.RaiseNotificationSent(sentNotifications[i].Notification);
                                        }
                                    }

                                    //The notification that failed needs to have a failure event raised
                                    // we don't requeue it because apple told us it failed for real
                                    this.Events.RaiseNotificationSendFailure(failedNotification.Notification,
                                                                             new NotificationFailureException(status, failedNotification.Notification));

                                    // finally, raise failure for anything after the index of this failed one
                                    // in the sent list, since we may have sent them but apple will have disregarded
                                    // anything after the failed one and not told us about it
                                    if (failedNotificationIndex < sentNotifications.Count - 1)
                                    {
                                        //Requeue the failed notification since we're not sure it's a bad
                                        // notification, just that it was sent after a bad one was
                                        for (int i = failedNotificationIndex + 1; i <= sentNotifications.Count - 1; i++)
                                        {
                                            this.QueueNotification(sentNotifications[i].Notification, false);
                                        }
                                    }

                                    //Now clear out the sent list since we processed them all manually above
                                    sentNotifications.Clear();
                                }

                                //Start reading again
                                Reader();
                            }
                            else
                            {
                                connected = false;
                            }
                        }
                        catch
                        {
                            connected = false;
                        }
                    }                     // End Lock
                }), null);
            }
            catch
            {
                connected = false;
            }
        }
Exemple #4
0
        private void Cleanup()
        {
            int num = -1;

            try
            {
                num = Interlocked.CompareExchange(ref this.cleanupSync, 1, 0);
                if (num != 0)
                {
                    return;
                }
                bool flag;
                do
                {
                    lock (this.connectLock)
                    {
                        try
                        {
                            this.Connect();
                        }
                        catch (Exception ex)
                        {
                            PushChannelExceptionDelegate onException = this.OnException;
                            if (onException != null)
                            {
                                onException((object)this, ex);
                            }
                        }
                    }
                    flag = false;
                    lock (this.sentLock)
                    {
                        if (this.sentNotifications.Count > 0)
                        {
                            if (this.connected)
                            {
                                SentNotification sentNotification = this.sentNotifications[0];
                                if (sentNotification.SentAt < DateTime.UtcNow.AddMilliseconds((double)(-1 * this.appleSettings.MillisecondsToWaitBeforeMessageDeclaredSuccess)))
                                {
                                    flag = true;
                                    Interlocked.Decrement(ref this.trackedNotificationCount);
                                    if (sentNotification.Callback != null)
                                    {
                                        sentNotification.Callback((object)this, new SendNotificationResult((INotification)sentNotification.Notification, false, (Exception)null));
                                    }
                                    this.sentNotifications.RemoveAt(0);
                                    Interlocked.Increment(ref this.cleanedUp);
                                }
                                else
                                {
                                    flag = false;
                                }
                            }
                            else
                            {
                                try
                                {
                                    this.sentNotifications[0].SentAt = DateTime.UtcNow;
                                }
                                catch
                                {
                                }
                            }
                        }
                    }
                }while (flag);
            }
            finally
            {
                if (num == 0)
                {
                    this.cleanupSync = 0;
                }
            }
        }
 public AbortedQueueContents(IEnumerable<SentNotification> completedItems, SentNotification failedNotification, IEnumerable<SentNotification> itemsIgnoredByApple)
 {
     this.ItemsIgnoredByApple = itemsIgnoredByApple;
     this.FailedNotification = failedNotification;
     this.CompletedItems = completedItems;
 }