private void WriteNotification(bool asyncOperation, double throttleInterval, IPendingRequestNotifier notifier, PendingRequestManager.PendingNotifierState notifierState) { bool flag = false; if (notifier.ShouldThrottle) { int num = notifierState.IncrementOnDataAvailableThrottleCount(); if (num > 100) { flag = true; } else if (num == 100 && throttleInterval <= 10.0) { ExTraceGlobals.NotificationsCallTracer.TraceDebug <string, int>((long)this.GetHashCode(), "Start throttling mechanism - timer was started and from now on notifier {0} / {1} will be on throttling mode ", notifier.GetType().Name, notifier.GetHashCode()); flag = true; if (notifierState.ThrottleTimer == null) { notifierState.ThrottleTimer = new Timer(new TimerCallback(this.ThrottleTimeout), notifier, 20000, -1); } else { notifierState.ThrottleTimer.Change(20000, -1); } } if (num <= 100 && throttleInterval > 10.0 && num != 1) { notifierState.ExchangeOnDataAvailableThrottleCount(1); } } if (flag) { ExTraceGlobals.NotificationsCallTracer.TraceDebug <string, int>((long)this.GetHashCode(), "PendingRequestManager.WriteNotification throttled notifier: {0} / {1}", notifier.GetType().Name, notifier.GetHashCode()); return; } ExTraceGlobals.NotificationsCallTracer.TraceDebug <string, int>((long)this.GetHashCode(), "PendingRequestManager.WriteNotification is reading data from the notifier. Notifier: {0} / {1}", notifier.GetType().Name, notifier.GetHashCode()); try { List <NotificationPayloadBase> payloadList = (List <NotificationPayloadBase>)notifier.ReadDataAndResetState(); if (notifier.SubscriptionId != null) { Pusher.Instance.Distribute(payloadList, notifier.ContextKey, notifier.SubscriptionId); } if (this.pendingRequestChannels != null) { lock (this.pendingRequestChannels) { if (this.pendingRequestChannels != null) { if (this.budget == null) { this.budget = StandardBudget.Acquire(this.userContext.ExchangePrincipal.Sid, BudgetType.Owa, this.userContext.ExchangePrincipal.MailboxInfo.OrganizationId.ToADSessionSettings()); } this.budget.CheckOverBudget(); this.budget.StartLocal("PendingRequestManager.WriteNotification", default(TimeSpan)); try { using (Dictionary <string, PendingRequestChannel> .Enumerator enumerator = this.pendingRequestChannels.GetEnumerator()) { while (enumerator.MoveNext()) { KeyValuePair <string, PendingRequestChannel> channel = enumerator.Current; try { OwaDiagnostics.SendWatsonReportsForGrayExceptions(delegate() { KeyValuePair <string, PendingRequestChannel> channel = channel; channel.Value.WritePayload(asyncOperation, payloadList); Dictionary <string, long> dictionary = this.channelNotificationMarks; KeyValuePair <string, PendingRequestChannel> channel2 = channel; if (dictionary.ContainsKey(channel2.Key)) { Dictionary <string, long> dictionary3; Dictionary <string, long> dictionary2 = dictionary3 = this.channelNotificationMarks; KeyValuePair <string, PendingRequestChannel> channel3 = channel; string key; dictionary2[key = channel3.Key] = dictionary3[key] + (long)payloadList.Count; return; } Dictionary <string, long> dictionary4 = this.channelNotificationMarks; KeyValuePair <string, PendingRequestChannel> channel4 = channel; dictionary4.Add(channel4.Key, (long)payloadList.Count); }); } catch (GrayException ex) { Exception ex2 = (ex.InnerException != null) ? ex.InnerException : ex; ExTraceGlobals.NotificationsCallTracer.TraceError((long)this.GetHashCode(), "Exception when writing the notifications to the client. Notifier {0} / {1}, exception message: {2}, stack: {3};", new object[] { notifier.GetType().Name, notifier.GetHashCode(), ex2.Message, ex2.StackTrace }); } } } } finally { this.budget.EndLocal(); } } } } } catch (Exception ex3) { ExTraceGlobals.NotificationsCallTracer.TraceError <string, int, string>((long)this.GetHashCode(), "Exception when writing the notifications to the client. Notifier {0} / {1}, exception message: {2};", notifier.GetType().Name, notifier.GetHashCode(), (ex3.InnerException != null) ? ex3.InnerException.Message : ex3.Message); throw; } }
private void ThrottleTimeout(object state) { ExTraceGlobals.NotificationsCallTracer.TraceDebug((long)this.GetHashCode(), "Throttle Timeout method was called - throttle timeout elapsed"); IPendingRequestNotifier pendingRequestNotifier = state as IPendingRequestNotifier; bool flag = false; try { if (pendingRequestNotifier == null) { throw new ArgumentException("State paramenter is invalid"); } this.notifiersStateLock.LockReaderElastic(5000); flag = true; PendingRequestManager.PendingNotifierState pendingNotifierState = null; if (!this.notifierDataAvaiableState.TryGetValue(pendingRequestNotifier, out pendingNotifierState)) { throw new ArgumentException("The sender object is not registered in the manager class"); } Interlocked.Exchange(ref pendingNotifierState.OnDataAvailableThrottleCount, 0); ExTraceGlobals.NotificationsCallTracer.TraceDebug <int>((long)this.GetHashCode(), "Notifier {0} is not on throttle period anymore", pendingRequestNotifier.GetHashCode()); this.OnNotifierDataAvailable(pendingRequestNotifier, null); } catch (Exception e) { this.HandleException(e, false); } finally { if (flag) { this.notifiersStateLock.ReleaseReaderLock(); } } }
private void WriteNotification(bool asyncOperation) { ExTraceGlobals.NotificationsCallTracer.TraceDebug <SmtpAddress>((long)this.GetHashCode(), "Writing notifications for {0}.", this.userContext.ExchangePrincipal.MailboxInfo.PrimarySmtpAddress); bool flag = false; try { if (!this.notifiersStateLock.IsReaderLockHeld) { this.notifiersStateLock.LockReaderElastic(5000); flag = true; } TimeSpan value = new TimeSpan(DateTime.UtcNow.Ticks); double num = 0.0; if (this.startThrottleTime != null) { num = value.Subtract(this.startThrottleTime.Value).TotalSeconds; } if (this.startThrottleTime == null || num > 10.0) { this.startThrottleTime = new TimeSpan?(value); } foreach (KeyValuePair <IPendingRequestNotifier, PendingRequestManager.PendingNotifierState> keyValuePair in this.notifierDataAvailableState) { IPendingRequestNotifier key = keyValuePair.Key; PendingRequestManager.PendingNotifierState value2 = keyValuePair.Value; int num2 = value2.CompareExchangeState(0, 1); if (num2 != 1) { ExTraceGlobals.NotificationsCallTracer.TraceDebug <string, int, int>((long)this.GetHashCode(), "PendingRequestManager.WriteNotification is skipping notifier {0} / {1} with state {2}.", key.GetType().Name, key.GetHashCode(), num2); } else { this.WriteNotification(asyncOperation, num, key, value2); } } if (flag) { this.notifiersStateLock.ReleaseReaderLock(); flag = false; } } finally { if (flag) { this.notifiersStateLock.ReleaseReaderLock(); } } }