예제 #1
0
        internal void AddPendingRequestNotifier(IPendingRequestNotifier notifier)
        {
            LockCookie?lockCookie = null;

            try
            {
                if (notifier == null)
                {
                    throw new ArgumentNullException("notifier");
                }
                this.notifiersStateLock.LockWriterElastic(5000);
                this.notifierDataAvaiableState.Add(notifier, new PendingRequestManager.PendingNotifierState());
                notifier.DataAvailable += this.OnNotifierDataAvailable;
            }
            finally
            {
                if (this.notifiersStateLock.IsWriterLockHeld)
                {
                    if (lockCookie != null)
                    {
                        LockCookie value = lockCookie.Value;
                        this.notifiersStateLock.DowngradeFromWriterLock(ref value);
                    }
                    else
                    {
                        this.notifiersStateLock.ReleaseWriterLock();
                    }
                }
                if (lockCookie != null && !this.notifiersStateLock.IsReaderLockHeld)
                {
                    ExAssert.RetailAssert(true, "Lost readerwriterlock that was acquired before entering the method");
                }
            }
        }
예제 #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();
                }
            }
        }
예제 #4
0
        internal void OnNotifierDataAvailable(object sender, EventArgs args)
        {
            bool flag = false;

            try
            {
                this.notifiersStateLock.LockReaderElastic(5000);
                flag = true;
                if (sender == null)
                {
                    throw new ArgumentNullException("sender");
                }
                ExTraceGlobals.NotificationsCallTracer.TraceDebug <int>((long)this.GetHashCode(), "OnNotifierDataAvailable called by a notifier.Notifier:{0}", sender.GetHashCode());
                IPendingRequestNotifier key = (IPendingRequestNotifier)sender;
                PendingRequestManager.PendingNotifierState pendingNotifierState = null;
                if (!this.notifierDataAvaiableState.TryGetValue(key, out pendingNotifierState))
                {
                    throw new ArgumentException("The sender object is not registered in the manager class");
                }
                int num = Interlocked.CompareExchange(ref pendingNotifierState.State, 1, 0);
                if (num != 0)
                {
                    throw new OwaInvalidOperationException("OnNotifierDataAvailable should not be called if the manager did not consume the notifier's data yet. Notifier:" + sender.ToString());
                }
                if (this.lockTracker.TryAcquireLock())
                {
                    this.WriteNotification(false);
                }
            }
            catch (Exception e)
            {
                this.HandleException(e, false);
            }
            finally
            {
                if (flag)
                {
                    this.notifiersStateLock.ReleaseReaderLock();
                }
            }
        }
 internal void RemovePendingRequestNotifier(IPendingRequestNotifier notifier)
 {
     try
     {
         if (notifier == null)
         {
             throw new ArgumentNullException("notifier");
         }
         if (this.notifiersStateLock.LockWriterElastic(5000))
         {
             this.notifierDataAvailableState.Remove(notifier);
             notifier.DataAvailable -= this.OnNotifierDataAvailable;
         }
     }
     finally
     {
         if (this.notifiersStateLock.IsWriterLockHeld)
         {
             this.notifiersStateLock.ReleaseWriterLock();
         }
     }
 }
 internal void AddPendingRequestNotifier(IPendingRequestNotifier notifier)
 {
     try
     {
         if (notifier == null)
         {
             throw new ArgumentNullException("notifier");
         }
         if (this.notifiersStateLock.LockWriterElastic(5000))
         {
             this.notifierDataAvailableState.Add(notifier, new PendingRequestManager.PendingNotifierState());
             notifier.DataAvailable += this.OnNotifierDataAvailable;
         }
     }
     finally
     {
         if (this.notifiersStateLock.IsWriterLockHeld)
         {
             this.notifiersStateLock.ReleaseWriterLock();
         }
     }
 }
        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;
            }
        }