private void QueueNotification(INotification notification, bool countsAsRequeue = true, bool ignoreStoppingChannel = false, bool queueToFront = false) { this.lastNotificationQueueTime = DateTime.UtcNow; if (this.cancelTokenSource.IsCancellationRequested) { throw new ObjectDisposedException("Service", "Service has already been signaled to stop"); } if (this.ServiceSettings.MaxNotificationRequeues < 0 || notification.QueuedCount <= this.ServiceSettings.MaxNotificationRequeues) { Interlocked.Increment(ref this.trackedNotificationCount); notification.EnqueuedTimestamp = DateTime.UtcNow; if (countsAsRequeue) { ++notification.QueuedCount; } if (queueToFront) { this.queuedNotifications.EnqueueAtStart(notification); } else { this.queuedNotifications.Enqueue(notification); } this.waitQueuedNotifications.Set(); } else { NotificationFailedDelegate notificationFailed = this.OnNotificationFailed; if (notificationFailed != null) { notificationFailed((object)this, notification, (Exception) new MaxSendAttemptsReachedException()); } Log.Info("Notification ReQueued Too Many Times: {0}", (object)notification.QueuedCount); } }
private void DoChannelWork(IPushChannel channel, CancellationTokenSource cancelTokenSource) { string str = Guid.NewGuid().ToString(); long num = 0; while (!cancelTokenSource.IsCancellationRequested) { INotification notification = this.queuedNotifications.Dequeue(); if (notification == null) { Thread.Sleep(100); } else { ManualResetEvent waitForNotification = (ManualResetEvent)null; if (this.BlockOnMessageResult) { waitForNotification = new ManualResetEvent(false); } double totalMilliseconds = (DateTime.UtcNow - notification.EnqueuedTimestamp).TotalMilliseconds; lock (this.measurementsLock) this.measurements.Add(new PushServiceBase.WaitTimeMeasurement((long)totalMilliseconds)); DateTime sendStart = DateTime.UtcNow; ++num; Interlocked.Increment(ref this.totalSendCount); if (num % 1000L == 0L) { Log.Debug("{0}> Send Count: {1} ({2})", (object)str, (object)num, (object)Interlocked.Read(ref this.totalSendCount)); } channel.SendNotification(notification, (SendNotificationCallbackDelegate)((sender, result) => { Interlocked.Decrement(ref this.trackedNotificationCount); TimeSpan timeSpan = DateTime.UtcNow - sendStart; lock (this.sendTimeMeasurementsLock) this.sendTimeMeasurements.Add(new PushServiceBase.WaitTimeMeasurement((long)timeSpan.TotalMilliseconds)); waitForNotification?.Set(); if (result.ShouldRequeue) { NotificationRequeueEventArgs e = new NotificationRequeueEventArgs(result.Notification, result.Error); NotificationRequeueDelegate notificationRequeue = this.OnNotificationRequeue; if (notificationRequeue != null) { notificationRequeue((object)this, e); } if (e.Cancel) { return; } this.QueueNotification(result.Notification, result.CountsAsRequeue, true, true); } else if (!result.IsSuccess) { if (result.IsSubscriptionExpired) { if (!string.IsNullOrEmpty(result.NewSubscriptionId)) { DeviceSubscriptionChangedDelegate subscriptionChanged = this.OnDeviceSubscriptionChanged; if (subscriptionChanged == null) { return; } subscriptionChanged((object)this, result.OldSubscriptionId, result.NewSubscriptionId, result.Notification); } else { DeviceSubscriptionExpiredDelegate subscriptionExpired = this.OnDeviceSubscriptionExpired; if (subscriptionExpired == null) { return; } subscriptionExpired((object)this, result.OldSubscriptionId, result.SubscriptionExpiryUtc, result.Notification); } } else { NotificationFailedDelegate notificationFailed = this.OnNotificationFailed; if (notificationFailed == null) { return; } notificationFailed((object)this, result.Notification, result.Error); } } else { NotificationSentDelegate notificationSent = this.OnNotificationSent; if (notificationSent == null) { return; } notificationSent((object)this, result.Notification); } })); if (waitForNotification != null && !waitForNotification.WaitOne(this.ServiceSettings.NotificationSendTimeout)) { Interlocked.Decrement(ref this.trackedNotificationCount); Log.Info("Notification send timeout"); NotificationFailedDelegate notificationFailed = this.OnNotificationFailed; if (notificationFailed != null) { notificationFailed((object)this, notification, (Exception) new TimeoutException("Notification send timed out")); } } if (waitForNotification != null) { waitForNotification.Close(); waitForNotification = (ManualResetEvent)null; } } } channel.Dispose(); }