示例#1
0
        /// <summary>
        /// Get a response from the storage
        /// </summary>
        /// <param name="callback">the response callback, the async result should be the BrokerQueueItem</param>
        /// <param name="callbackState">the state object for the callback</param>
        public void GetResponseAsync(PersistCallback callback, object callbackState)
        {
            if (this.isClosedField)
            {
                BrokerTracing.TraceWarning("[MemoryPersist] .GetResponseAsync: the queue is closed.");
                return;
            }

            BrokerQueueItem responseItem = null;

            try
            {
                lock (this.lockResponseQueueField)
                {
                    responseItem = this.responseQueueField.Dequeue();
                }
            }
            catch (InvalidOperationException)
            {
                BrokerTracing.TraceError("[MemoryPersist] .GetResponseAsync: no response available.  sessionId = {0}, clientId = {1}", this.sessionIdField, this.clientIdField);
            }

            if (callback == null)
            {
                return;
            }

            ThreadPool.QueueUserWorkItem(this.GetOperationComplete, new GetCallbackContext(callback, callbackState, responseItem));
        }
示例#2
0
            /// <summary>
            /// Initializes a new instance of the GetMessageState class.
            /// </summary>
            /// <param name="messageCallback">the callback that get the message</param>
            /// <param name="callbackState">the callback state object.</param>
            public GetMessageState(PersistCallback messageCallback, object callbackState)
            {
                if (messageCallback == null)
                {
                    throw new ArgumentNullException("messageCallback");
                }

                this.messageCallbackField = messageCallback;
                this.callbackStateField   = callbackState;
            }
示例#3
0
        public void Persist()
        {
            Log.Instance.LogFineDebug(string.Format("TaskListGroup.Persist"));

            if (PersistCallback != null)
            {
                PersistCallback.OnPersist();
            }
            else
            {
                Log.Instance.LogInfo(string.Format("TaskListGroup.Persist - PersistCallback is null, skipping"));
            }
        }
示例#4
0
        /// <summary>
        /// Fetch the requests one by one from the storage but not remove the original message in the storage.
        /// </summary>
        /// <param name="callback">the callback to get the async result</param>
        /// <param name="state">the state object for the callback</param>
        public void GetRequestAsync(PersistCallback callback, object state)
        {
            if (this.isClosedField)
            {
                BrokerTracing.TraceWarning("[MemoryPersist] .GetRequestAsync: the queue is closed.");
                return;
            }

            BrokerQueueItem requestItem = null;

            if (!this.requestQueueField.TryDequeue(out requestItem))
            {
                BrokerTracing.TraceError("[MemoryPersist] .GetRequestAsync: no request available. sessionId={0}, clientId={1}", this.sessionIdField, this.clientIdField);
            }

            if (callback == null)
            {
                return;
            }

            ThreadPool.QueueUserWorkItem(this.GetOperationComplete, new GetCallbackContext(callback, state, requestItem));
        }
示例#5
0
        public void GetMessageAsync(PersistCallback callback, object state)
        {
            if (this.isDisposedField)
            {
                BrokerTracing.TraceWarning(
                    "[AzureQueueMessageFetcher] .GetMessageAsync: fetcherId={0} the instance is disposed.",
                    this.fetcherId);
                return;
            }

            BrokerTracing.TraceVerbose(
                "[AzureQueueMessageFetcher] .GetMessageAsync: fetcherId={0} Get message come in.",
                this.fetcherId);

            // GetMessageAsync:
            // step 1, try to get message from prefetch cache. If succeeded, invoke the callback directly; or else,
            // step 2, save context of this GetMessageAsync call, including callback and callback state into this.currentGetMessageState, which will be handled when a message is retrieved back from MSMQ.
            // step 3, check if need to get more messages.  If so, initiate more BeginPeek calls into MSMQ
            GetMessageState       getMessageState = new GetMessageState(callback, state);
            MessageResult         result          = null;
            Queue <MessageResult> messageQueue    = new Queue <MessageResult>();

#if DEBUG
            bool getResponse = false;
#endif

            long getMessageCount = 1;
            ResponseCallbackItem responseCallbackItem = state as ResponseCallbackItem;
            if (responseCallbackItem != null)
            {
#if DEBUG
                getResponse = true;
#endif
                getMessageCount = responseCallbackItem.ExpectedResponseCount;
                Debug.WriteLine(
                    $"[AzureQueueMessageFetcher] .GetMessageAsync: working to get response. getMessageCount={getMessageCount}.");
            }
            else
            {
                Debug.WriteLine(
                    $"[AzureQueueMessageFetcher] .GetMessageAsync: working to get request. getMessageCount={getMessageCount}.");
            }

            this.lockPrefetchCache.EnterReadLock();
            try
            {
                if (this.prefetchCache == null)
                {
                    // this instance is disposed
                    BrokerTracing.TraceWarning(
                        "[AzureQueueMessageFetcher] .GetMessageAsync: the instance is disposed.");
                    return;
                }

                while (getMessageCount > 0)
                {
                    if (!(this.prefetchCache.Count > 0 && this.prefetchCache.TryDequeue(out result)))
                    {
                        BrokerTracing.TraceVerbose("[AzureQueueMessageFetcher] .GetMessageAsync: cache miss");
                        result = null;
                        this.currentGetMessageQueue.Enqueue(getMessageState);
                        break;
                    }

                    BrokerTracing.TraceVerbose("[AzureQueueMessageFetcher] .GetMessageAsync: hit cache");
                    messageQueue.Enqueue(result);
                    getMessageCount--;
                }
            }
            finally
            {
                this.lockPrefetchCache.ExitReadLock();
            }

            Debug.WriteLine(
                $"[AzureQueueMessageFetcher] .GetMessageAsync: getMessageCount={getMessageCount} after dequeue.");

            while (messageQueue.Any())
            {
                var message = messageQueue.Dequeue();
                if (message != null)
                {
                    // There is one more space available in prefetch cache
                    lock (this.lockFetchCount)
                    {
                        this.prefetchCredit++;
                    }

                    // GetMessageAsync is a light-weight call and is supposed to return very soon.  While in its callback,
                    // there may be time-consuming operations. So here we always invoke the callback in another thread.
                    ThreadPool.QueueUserWorkItem(
                        this.GetMessageAsyncCallback,
                        new object[] { getMessageState, message });
                }
                else
                {
                    BrokerTracing.TraceWarning(
                        "[AzureQueueMessageFetcher] .GetMessageAsync: fetcherId={0} encountered null message result.",
                        this.fetcherId);
                }
            }

            this.CheckAndGetMoreMessages();
        }
示例#6
0
 /// <summary>
 /// Instantiate a new instance of class GetCallbackContext
 /// </summary>
 /// <param name="callback">the callback</param>
 /// <param name="callbackState">the callback context</param>
 /// <param name="callbackMsg">the retrieved back message</param>
 public GetCallbackContext(PersistCallback callback, object callbackState, BrokerQueueItem callbackMsg)
 {
     this.callbackField      = callback;
     this.callbackStateField = callbackState;
     this.callbackMsgField   = callbackMsg;
 }