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;
            }
        }
예제 #2
0
        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();
                }
            }
        }