Beispiel #1
0
 /// <summary>
 /// Check the user name and throw exception if user name does not match
 /// </summary>
 /// <param name="brokerQueue">indicating the broker queue</param>
 /// <param name="userName">indicating the user name</param>
 private static void ThrowIfUserNameDoesNotMatch(BrokerQueue brokerQueue, string userName)
 {
     if (!string.Equals(userName, brokerQueue.UserName, StringComparison.OrdinalIgnoreCase))
     {
         throw new BrokerQueueException((int)BrokerQueueErrorCode.E_BQ_USER_NOT_MATCH, String.Format("the user name is not the user who create the queue. username: {0}, ownername={1}", userName, brokerQueue.UserName));
     }
 }
Beispiel #2
0
        internal void RemoveBrokerQueue(BrokerQueue queue)
        {
            if (queue != null)
            {
                bool containsQueue;
                lock (this.needDispatchQueueClientIdTable)
                {
                    containsQueue = this.needDispatchQueueClientIdTable.ContainsKey(queue.ClientId);
                }

                if (containsQueue)
                {
                    try
                    {
                        lock (this.needDispatchQueueClientIdTable)
                        {
                            this.needDispatchQueueClientIdTable.Remove(queue.ClientId);
                        }
                    }
                    catch (Exception e)
                    {
                        BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .RemoveBrokerQueue: Remove the broker queue with the client id, {0}, from the client table raised exception, {1}", queue.ClientId, e);
                    }
                }

                lock (this.waitBrokerQueuesForPeekRequests)
                {
                    this.waitBrokerQueuesForPeekRequests.Remove(queue);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Initializes a new instance of the ExceptionEventArgs class for the broker queue.
        /// </summary>
        /// <param name="exception">the exception.</param>
        /// <param name="queue">the client id.</param>
        internal ExceptionEventArgs(Exception exception, BrokerQueue queue)
            : base(queue)
        {
            if (exception == null)
            {
                throw new ArgumentNullException("exception");
            }

            this.exceptionField = exception;
        }
Beispiel #4
0
        private bool HandleResponseWithoutAsyncToken(BrokerQueue queue, BrokerQueueItem requestItem)
        {
            bool   isHandled        = false;
            Guid   persistId        = requestItem.PersistId;
            object asyncToken       = requestItem.PersistAsyncToken.AsyncToken;
            int    dispatcherNumber = requestItem.DispatchNumber;

            if (asyncToken != null && this.responsesWithoutAsyncTokenTable.Count > 0)
            {
                bool needPutResponse = false;
                DispatcherAsyncTokenItem asyncTokenItem = null;
                try
                {
                    lock (this.responsesWithoutAsyncTokenTable)
                    {
                        this.responsesWithoutAsyncTokenTable.TryGetValue(persistId, out asyncTokenItem);
                    }

                    if (asyncTokenItem != null)
                    {
                        lock (this.responsesWithoutAsyncTokenTable)
                        {
                            this.responsesWithoutAsyncTokenTable.Remove(persistId);
                        }

                        needPutResponse = true;

                        lock (this.requestsAsyncTokenTable)
                        {
                            this.requestsAsyncTokenTable.Remove(persistId);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (needPutResponse)
                    {
                        BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PrefetchRequestCallback: fail to remove the async token from the table, Exception: {0}", e);
                    }
                    else
                    {
                        BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PrefetchRequestCallback: can not get the response async token, Exception: {0}", e);
                    }
                }

                if (needPutResponse && dispatcherNumber == 0)
                {
                    asyncTokenItem.PersistAsyncToken.AsyncToken = asyncToken;
                    queue.PutResponseAsync(asyncTokenItem.Message, requestItem);
                    isHandled = true;
                }
            }
            return(isHandled);
        }
Beispiel #5
0
        /// <summary>
        /// trigger the prefetch operation.
        /// </summary>
        private void TriggerPrefetch()
        {
            this.needPrefetch = true;
            while (this.needPrefetch && this.waitBrokerQueuesForPeekRequests.Count > 0)
            {
                BrokerQueue queue = null;
                lock (this.waitBrokerQueuesForPeekRequests)
                {
                    if (this.waitBrokerQueuesForPeekRequests.Count > 0)
                    {
                        queue = this.waitBrokerQueuesForPeekRequests[this.waitBrokerQueuesForPeekRequests.Count - 1];
                        this.waitBrokerQueuesForPeekRequests.Remove(queue);
                    }
                }

                if (queue != null)
                {
                    ThreadPool.QueueUserWorkItem(this.waitCallbackToGetRequestAsync, queue);
                }
            }
        }
Beispiel #6
0
        public BrokerQueue GetPersistQueueByClient(string clientId, string userName, out bool isNewCreate)
        {
            BrokerTracing.TraceInfo($"[GetPersistQueueByClient] username:{userName}, sessionid:{this.sessionId}, client:{clientId}");
            isNewCreate = false;
            if (string.IsNullOrEmpty(clientId))
            {
                clientId = BrokerQueueFactory.defaultClientId;
            }

            BrokerQueue brokerQueue = null;

            lock (this.clientBrokerQueueDic)
            {
                this.clientBrokerQueueDic.TryGetValue(clientId, out brokerQueue);
            }

            if (brokerQueue == null)
            {
                lock (this.thisLockObj)
                {
                    lock (this.clientBrokerQueueDic)
                    {
                        this.clientBrokerQueueDic.TryGetValue(clientId, out brokerQueue);
                    }

                    if (brokerQueue == null)
                    {
                        ISessionPersist sessionPersist = null;
                        if (string.IsNullOrEmpty(this.persistName))
                        {
                            sessionPersist = new MemoryPersist(userName, this.sessionId, clientId);
                            brokerQueue    = new BrokerPersistQueue(
                                this.brokerQueueDispatcher,
                                this.persistName,
                                this.sessionId,
                                clientId,
                                sessionPersist,
                                1,    // no request cache
                                // no request cache
                                1,    // no response cache
                                // no response cache
                                0,    // no timeout
                                // no timeout
                                false,
                                // no in-memory cache
                                this.sharedData,
                                this);
                            this.brokerQueueDispatcher.AddBrokerQueue(brokerQueue, null);
                        }
                        else
                        {
                            ParamCheckUtility.ThrowIfNull(this.sharedData.BrokerInfo.AzureStorageConnectionString, "StorageConnectString");

                            sessionPersist = new AzureQueuePersist(userName, this.sessionId, clientId, this.sharedData.BrokerInfo.AzureStorageConnectionString);
                            isNewCreate    = sessionPersist.IsNewCreated;
                            brokerQueue    = new BrokerPersistQueue(
                                this.brokerQueueDispatcher,
                                this.persistName,
                                this.sessionId,
                                clientId,
                                sessionPersist,
                                BrokerQueueConstants.DefaultThresholdForRequestPersist,
                                BrokerQueueConstants.DefaultThresholdForResponsePersist,
                                BrokerQueueConstants.DefaultMessagesInCacheTimeout,
                                isNewCreate,  // need in-memory quick cache for newly-created durable queue
                                // need in-memory quick cache for newly-created durable queue
                                this.sharedData,
                                this);

                            //
                            // For an existing durable queue, if EndOfMessage is not received, or there are requests waiting to be processed,
                            // then schedule the broker queue for dispatching;
                            // for an newly created durable queue, it will be added to brokerQueueDispatcher when BrokerQueuePersist.Flush
                            // is called (with quick cache filled), so no need to call AddBrokerQueue here (bug #21453)
                            //
                            if (!isNewCreate && (!brokerQueue.EOMReceived || sessionPersist.RequestsCount > 0))
                            {
                                this.brokerQueueDispatcher.AddBrokerQueue(brokerQueue, null);
                            }
                        }

                        lock (this.clientBrokerQueueDic)
                        {
                            this.clientBrokerQueueDic.Add(clientId, brokerQueue);
                        }
                    }
                }
            }

            // Bug 6313: Check the user name
            ThrowIfUserNameDoesNotMatch(brokerQueue, userName);
            return(brokerQueue);
        }
Beispiel #7
0
        /// <summary>
        /// Callback to get request
        /// </summary>
        /// <param name="state">indicating the state</param>
        private void WaitCallbackToGetRequestAsync(object state)
        {
            BrokerQueue queue = (BrokerQueue)state;

            queue.GetRequestAsync(this.PrefetchRequestCallback, queue);
        }
Beispiel #8
0
        private void PrefetchRequestCallback(BrokerQueueItem queueItem, object state)
        {
            try
            {
#if DEBUG
                BrokerTracing.TraceVerbose("[BrokerQueueDispatcher] .PrefetchRequestCallback: received one request. request id={0}", GetMessageId(queueItem));
#endif
                bool   isCached = false;
                bool   shouldDisposeQueueItem = false;
                Guid   persistId        = Guid.Empty;
                object asyncToken       = null;
                int    dispatcherNumber = 0;
                if (queueItem != null)
                {
                    dispatcherNumber = queueItem.DispatchNumber;
                    persistId        = queueItem.PersistId;
                    asyncToken       = queueItem.PersistAsyncToken.AsyncToken;
                    if (this.requestsAsyncTokenTable.Count > 0 && dispatcherNumber == 0)
                    {
                        // if the request is already in the cache or dispatched.
                        lock (this.requestsAsyncTokenTable)
                        {
                            if (this.requestsAsyncTokenTable.ContainsKey(persistId))
                            {
                                try
                                {
                                    DispatcherAsyncTokenItem asyncTokenItem = this.requestsAsyncTokenTable[persistId];
                                    if (asyncTokenItem.AsyncToken == null)
                                    {
                                        asyncTokenItem.AsyncToken = asyncToken;
                                    }

                                    // the duplicated request item is of no use after retrieving out its async token.  so we should dispose it if possible
                                    shouldDisposeQueueItem = true;
                                }
                                catch (Exception e)
                                {
                                    // the request in the table is removed by another thread.
                                    BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PrefetchRequestCallback: The request async token is removed from the table, Exception: {0}", e);
                                }

                                isCached = true;
                            }
                        }
                    }

                    if (!isCached)
                    {
                        bool needQueue = true;

                        // if there are pending requests callback, then dispatch the request through the pending requests callback.
                        if (this.requestCallbackQueue.Count > 0)
                        {
                            try
                            {
                                BrokerQueueCallbackItem requestCallback;
                                if (this.requestCallbackQueue.TryDequeue(out requestCallback))
                                {
                                    this.RegisterReemit(queueItem);

                                    requestCallback.Callback(queueItem, requestCallback.CallbackState);
                                    needQueue = false;
#if DEBUG
                                    BrokerTracing.TraceVerbose("[BrokerQueueDispatcher] .PrefetchRequestCallback: Invoked callback for request.");
#endif
                                }
                                else
                                {
                                    BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PrefetchRequestCallback: The requests callback queue is empty.");
                                }
                            }
                            catch (InvalidOperationException e)
                            {
                                // the request callback queue is drained by other threads.
                                BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PrefetchRequestCallback: The requests callback queue is empty, Exception: {0}", e);
                            }
                            catch (Exception e)
                            {
                                // request callback raise exception.
                                BrokerTracing.TraceWarning("[BrokerQueueDispatcher] .PrefetchRequestCallback: The requests callback raise exception, Exception: {0}", e);
                            }
                        }

                        if (needQueue)
                        {
                            // if no pending requests callback, then append the request to the cache queue.
                            this.requestCacheQueue.Enqueue(queueItem);
                            if (this.requestCacheQueue.Count >= this.GetCacheContainerSize())
                            {
                                this.needPrefetch = false;
                            }
                            else
                            {
                                this.needPrefetch = true;
                            }
                        }
                    }
                }

                BrokerQueue brokerQueue = (BrokerQueue)state;

                // try to get the next request.
                if (this.needPrefetch)
                {
                    // hop to another thread to avoid recursive stack overflow for memory queue that will call the callback at the same thread.
                    ThreadPool.QueueUserWorkItem(this.GetRequestThreadProc, state);
                }
                else
                {
                    lock (this.waitBrokerQueuesForPeekRequests)
                    {
                        this.waitBrokerQueuesForPeekRequests.Add(brokerQueue);
                    }

                    if (this.requestCacheQueue.Count < this.sharedData.DispatcherCount + this.watermarkerForTriggerPrefetch)
                    {
                        this.TriggerPrefetch();
                    }
                }

                // drain the pending requests callback.
                this.HandlePendingRequestCallback();

                // check if the response already come back.
                if (!this.HandleResponseWithoutAsyncToken(brokerQueue, queueItem) && shouldDisposeQueueItem)
                {
                    // if its response is not back, and we've decided that the request queue item is of no use, dispose it.
                    queueItem.Dispose();
                }
            }
            catch (Exception e)
            {
                BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PrefetchRequestCallback: raised unknown exception: {0}", e);
            }
        }
Beispiel #9
0
        internal void AddBrokerQueue(BrokerQueue queue, IEnumerable <BrokerQueueItem> requests)
        {
            if (queue != null)
            {
                if (requests != null)
                {
                    foreach (BrokerQueueItem request in requests)
                    {
                        if (request != null)
                        {
                            if (request.PersistAsyncToken.AsyncToken == null)
                            {
                                lock (this.requestsAsyncTokenTable)
                                {
                                    if (!this.requestsAsyncTokenTable.ContainsKey(request.PersistId))
                                    {
                                        this.requestsAsyncTokenTable.Add(request.PersistId, new DispatcherAsyncTokenItem());
                                    }
                                    else
                                    {
                                        BrokerTracing.TraceError("[BrokerQueueDispatcher] .AddBrokerQueue: There are duplicate persist id, {0}", request.PersistId);
                                    }
                                }
                            }

                            this.requestCacheQueue.Enqueue(request);
                        }
                    }
                }

                bool containsQueue;
                lock (this.needDispatchQueueClientIdTable)
                {
                    containsQueue = this.needDispatchQueueClientIdTable.ContainsKey(queue.ClientId);
                }

                if (!containsQueue)
                {
                    bool needDispatch = true;
                    try
                    {
                        lock (this.needDispatchQueueClientIdTable)
                        {
                            this.needDispatchQueueClientIdTable.Add(queue.ClientId, null);
                        }
                    }
                    catch (ArgumentException e)
                    {
                        needDispatch = false;

                        // the key already exists in the table.
                        BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .AddBrokerQueue: the broker queue with client id, {0}, already exists, Exception: {1}", queue.ClientId, e);
                    }
                    catch (Exception e)
                    {
                        BrokerTracing.TraceWarning("[BrokerQueueDispatcher] .AddBrokerQueue: add a broker queue with client id, {0}, to the client table raised exception, Exception: {1}", queue.ClientId, e);
                    }

                    if (needDispatch)
                    {
                        if (this.needPrefetch)
                        {
                            queue.GetRequestAsync(this.PrefetchRequestCallback, queue);
                        }
                        else
                        {
                            lock (this.waitBrokerQueuesForPeekRequests)
                            {
                                this.waitBrokerQueuesForPeekRequests.Add(queue);
                            }
                        }
                    }
                }
            }
        }
Beispiel #10
0
 /// <summary>
 /// Initializes a new instance of the BrokerQueueEventArgs class.
 /// </summary>
 /// <param name="queue">the broker queue.</param>
 public BrokerQueueEventArgs(BrokerQueue queue)
 {
     this.queueField = queue;
 }