Beispiel #1
0
            /// <summary>
            /// Start the timer.
            /// </summary>
            private void TriggerTimer()
            {
                if (this.stop)
                {
                    lock (this.timerStopLock)
                    {
                        if (this.stop)
                        {
                            this.timerStopped = true;
                            BrokerTracing.TraceInfo(
                                SoaHelper.CreateTraceMessage(
                                    "MessageSender.Worker",
                                    "TriggerTimer",
                                    "Worker stops."));
                            return;
                        }
                        else
                        {
                            this.timerStopped = false;
                        }
                    }
                }

                try
                {
                    BrokerTracing.TraceInfo(
                        SoaHelper.CreateTraceMessage(
                            "MessageSender.Worker",
                            "TriggerTimer",
                            "Timer triggered with sleep time {0}.", this.sleepPeriod));

                    this.timer.Change(this.sleepPeriod, Timeout.Infinite);

                    if (this.sleepPeriod == 0)
                    {
                        this.sleepPeriod = MinSleepTime;
                    }
                    else
                    {
                        this.sleepPeriod *= 2;

                        if (this.sleepPeriod > MaxSleepTime)
                        {
                            this.sleepPeriod = MaxSleepTime;
                        }
                    }
                }
                catch (NullReferenceException)
                {
                    TraceUtils.TraceWarning(
                        "MessageSender.Worker",
                        "TriggerTimer",
                        "NullReferenceException occurs when timer is being disposed.");
                }
                catch (Exception e)
                {
                    TraceUtils.TraceError("MessageSender.Worker", "TriggerTimer", "Error occurs, {0}", e);
                }
            }
        /// <summary>
        /// Invoke callback.
        /// </summary>
        /// <param name="asyncResults">a collection of IAsyncResult</param>
        private void InvokeCallback(ICollection <IAsyncResult> asyncResults)
        {
            try
            {
                asyncResults.AsParallel <IAsyncResult>().ForAll <IAsyncResult>(
                    (asyncResult) =>
                {
                    try
                    {
                        var reliableState = asyncResult.AsyncState as ReliableState;

                        if (!reliableState.CallbackInvoked())
                        {
                            TraceUtils.TraceWarning(
                                "ReliableQueueClient",
                                "InvokeCallback",
                                "Timeout happens, expected trigger time of message {0} is {1}, client {2}",
                                reliableState.MessageId,
                                reliableState.TriggerTime.ToLocalTime(),
                                this.clientId);

                            reliableState.Timeout = true;

                            reliableState.Callback(asyncResult);
                        }
                        else
                        {
                            TraceUtils.TraceVerbose(
                                "ReliableQueueClient",
                                "InvokeCallback",
                                "Callback of message {0} is already invoked, client {1}",
                                reliableState.MessageId,
                                this.clientId);
                        }
                    }
                    catch (Exception e)
                    {
                        TraceUtils.TraceError(
                            "ReliableQueueClient",
                            "InvokeCallback",
                            "Invoking callback failed, {0}, client {1}",
                            e,
                            this.clientId);
                    }
                });
            }
            catch (Exception e)
            {
                TraceUtils.TraceError(
                    "ReliableQueueClient",
                    "InvokeCallback",
                    "Error occurs, {0}, client {1}",
                    e,
                    this.clientId);
            }
        }
Beispiel #3
0
            /// <summary>
            /// Start the timer.
            /// </summary>
            private void TriggerTimer()
            {
                if (this.stop)
                {
                    TraceUtils.TraceWarning(
                        "MessageRetriever.Worker",
                        "TriggerTimer",
                        "Worker stops, worker {0}, queue {1}",
                        this.workerId,
                        this.queue.Name);

                    return;
                }

                try
                {
                    this.timer.Change(this.sleepPeriod, Timeout.Infinite);

                    if (this.sleepPeriod == 0)
                    {
                        this.sleepPeriod = MinSleepTime;
                    }
                    else
                    {
                        this.sleepPeriod *= 2;

                        if (this.sleepPeriod > MaxSleepTime)
                        {
                            this.sleepPeriod = MaxSleepTime;
                        }
                    }
                }
                catch (NullReferenceException)
                {
                    TraceUtils.TraceWarning(
                        "MessageRetriever.Worker",
                        "TriggerTimer",
                        "NullReferenceException occurs when timer is being disposed, worker {0}, queue {1}",
                        this.workerId,
                        this.queue.Name);
                }
                catch (Exception e)
                {
                    TraceUtils.TraceError(
                        "MessageRetriever.Worker",
                        "TriggerTimer",
                        "Error occurs, worker {0}, queue {1}, {2}",
                        this.workerId,
                        this.queue.Name,
                        e);
                }
            }
Beispiel #4
0
            /// <summary>
            /// Dispose the object.
            /// </summary>
            /// <param name="disposing">disposing flag</param>
            protected override void Dispose(bool disposing)
            {
                base.Dispose(disposing);

                if (disposing)
                {
                    try
                    {
                        // set stop flag
                        this.stop = true;

                        if (this.timer != null)
                        {
                            try
                            {
                                this.timer.Dispose();
                            }
                            catch (Exception ex)
                            {
                                // ignore the error here
                                TraceUtils.TraceWarning("MessageSender.Worker", "Dispose", "Exception while disposing timer {0}", ex);
                            }

                            this.timer = null;
                        }

                        // wait for callback to be called in case there is
                        // on-the-fly async call
                        if (!this.waitHandler.Wait(TimeSpan.FromSeconds(5)))
                        {
                            TraceUtils.TraceWarning("MessageSender.Worker", "Dispose", "WaitHandler.Wait timeout happens.");
                        }

                        try
                        {
                            this.waitHandler.Dispose();
                        }
                        catch
                        {
                        }

                        this.waitHandler = null;
                    }
                    catch (Exception e)
                    {
                        TraceUtils.TraceError("MessageSender.Worker", "Dispose", "Error occurs, {0}", e);
                    }
                }
            }
Beispiel #5
0
        /// <summary>
        /// Async method for add message. If the message size hits limit, store
        /// it in blob and add a referral message in queue.
        /// </summary>
        /// <param name="messageData">raw data of message</param>
        /// <param name="messageId">wcf message Id</param>
        /// <param name="callback">callback method</param>
        /// <param name="state">state object</param>
        /// <returns>async state</returns>
        public IAsyncResult BeginAddMessage(byte[] messageData, UniqueId messageId, AsyncCallback callback, ReliableQueueClient.ReliableState state)
        {
            CloudQueueMessage message = new CloudQueueMessage(messageData);

            try
            {
                if (messageData.Length <= MessageSizeBoundary)
                {
                    message = new CloudQueueMessage(messageData);

                    return(this.ReliableQueue.BeginAddMessage(message, callback, state));
                }
            }
            catch (ArgumentException e)
            {
                // according to the test, when payload is <= 48KB, it can fit
                // in a queue message. otherwise, ArgumentException occurs. but
                // there is no doc about this. so catch ArgumentException here,
                // and store message to blob below.
                TraceUtils.TraceWarning("AzureStorageClient", "BeginAddMessage", "BeginAddMessage failed, {0}", e);
            }
            catch (Exception ex)
            {
                TraceUtils.TraceWarning("AzureStorageClient", "BeginAddMessage", "BeginAddMessage failed, {0}", ex);
                throw;
            }

            TraceUtils.TraceVerbose("AzureStorageClient", "BeginAddMessage", "Upload message {0} to storage blob.", messageId);

            this.UploadBlob(messageData, messageId);

            // Store a referral message in Azure queue with the same message Id
            // as the original message. It redirects proxy to get real message
            // from the blob.
            Message referralMessage = Message.CreateMessage(MessageVersion.Default, string.Empty);

            referralMessage.Headers.MessageId = messageId;

            referralMessage.Headers.Add(
                MessageHeader.CreateHeader(Constant.MessageHeaderBlob, Constant.HpcHeaderNS, string.Empty));

            message = new CloudQueueMessage(AzureQueueItem.Serialize(referralMessage));

            return(this.ReliableQueue.BeginAddMessage(message, callback, state));
        }
        /// <summary>
        /// Dispose current object.
        /// </summary>
        /// <param name="disposing">disposing flag</param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (disposing)
            {
                if (this.timer != null)
                {
                    try
                    {
                        this.timer.Dispose();
                    }
                    catch (Exception e)
                    {
                        TraceUtils.TraceError(
                            "ReliableQueueClient",
                            "Dispose",
                            "Dispose timer failed, {0}, client {1}",
                            e,
                            this.clientId);
                    }

                    this.timer = null;
                }

                // Trigger TimeoutException on each item in asyncResultQueue.
                // Otherwise if callback lost, we don't have a way to recover
                // from that.
                int count = this.asyncResultCache.Count;

                if (count > 0)
                {
                    TraceUtils.TraceWarning(
                        "ReliableQueueClient",
                        "Dispose",
                        "Trigger TimeoutException on each item in asyncResultQueue, count {0}, client {1}",
                        count,
                        this.clientId);

                    this.InvokeCallback(this.asyncResultCache.Values);
                }
            }
        }
Beispiel #7
0
            /// <summary>
            /// Dispose the object.
            /// </summary>
            /// <param name="disposing">disposing flag</param>
            protected override void Dispose(bool disposing)
            {
                base.Dispose(disposing);

                if (disposing)
                {
                    try
                    {
                        // set stop flag
                        this.stop = true;

                        if (this.timer != null)
                        {
                            try
                            {
                                this.timer.Dispose();
                            }
                            catch (Exception ex)
                            {
                                TraceUtils.TraceWarning(
                                    "MessageRetriever.Worker",
                                    "Dispose",
                                    "Disposing timer exception {0}",
                                    ex);
                            }

                            this.timer = null;
                        }

                        // wait for callback to be called in case there is
                        // on-the-fly async call
                        if (!this.waitHandler.Wait(TimeSpan.FromSeconds(5)))
                        {
                            TraceUtils.TraceWarning(
                                "MessageRetriever.Worker",
                                "Dispose",
                                "WaitHandler.Wait timeout happens, worker {0}, queue {1}",
                                this.workerId,
                                this.queue.Name);
                        }

                        try
                        {
                            this.waitHandler.Dispose();
                        }
                        catch (Exception ex)
                        {
                            TraceUtils.TraceWarning(
                                "MessageRetriever.Worker",
                                "Dispose",
                                "Disposing waitHandler exception {0}",
                                ex);
                        }

                        this.waitHandler = null;
                    }
                    catch (Exception e)
                    {
                        TraceUtils.TraceError(
                            "MessageRetriever.Worker",
                            "Dispose",
                            "Error occurs, worker {0}, queue {1}, {2}",
                            this.workerId,
                            this.queue.Name,
                            e);
                    }
                }
            }
Beispiel #8
0
        public void PutResponseAsync(Message responseMsg, BrokerQueueItem requestItem, bool ignoreAsyncToken = false)
        {
            try
            {
                // Null means the request has been put back.
                if (responseMsg != null && this.sharedData.Config.LoadBalancing.MessageResendLimit > 0)
                {
                    if (!requestItem.ReemitToken.Finish())
                    {
                        TraceUtils.TraceWarning(
                            "BrokerQueueDispatcher",
                            "PutResponseAsync",
                            "Drop the response {0} since no multi emission callback registered",
                            Utility.GetMessageIdFromMessage(requestItem.Message));

                        return;
                    }
                }

                BrokerQueueAsyncToken asyncToken = requestItem.PersistAsyncToken;
                if (asyncToken.AsyncToken != null || ignoreAsyncToken || responseMsg == null)
                {
                    asyncToken.Queue.PutResponseAsync(responseMsg, requestItem);
                    return;
                }

                DispatcherAsyncTokenItem asyncTokenItem = null;
                lock (this.requestsAsyncTokenTable)
                {
                    this.requestsAsyncTokenTable.TryGetValue(asyncToken.PersistId, out asyncTokenItem);
                }

                if (asyncTokenItem != null)
                {
                    bool hasGetAsyncToken = false;
                    try
                    {
                        if (asyncTokenItem != null)
                        {
                            if (asyncTokenItem.AsyncToken != null)
                            {
                                asyncToken.AsyncToken = asyncTokenItem.AsyncToken;
                                hasGetAsyncToken      = true;

                                lock (this.requestsAsyncTokenTable)
                                {
                                    this.requestsAsyncTokenTable.Remove(asyncToken.PersistId);
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        if (hasGetAsyncToken)
                        {
                            BrokerTracing.TraceWarning("[BrokerQueueDispatcher] .PutResponseAsync: remove the async token from the table raised the exception, {0}", e);
                        }
                        else
                        {
                            // maybe there are duplicate responses, and the request in the async token table is removed by the previous request.
                            BrokerTracing.TraceWarning("[BrokerQueueDispatcher] .PutResponseAsync: try to get the async token from the table raised the exception, {0}", e);
                        }
                    }

                    if (hasGetAsyncToken)
                    {
                        asyncToken.Queue.PutResponseAsync(responseMsg, requestItem);
                    }
                    else
                    {
                        BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PutResponseAsync: Failed to get async token.");

                        lock (this.responsesWithoutAsyncTokenTable)
                        {
                            this.responsesWithoutAsyncTokenTable.Add(asyncToken.PersistId, new DispatcherAsyncTokenItem(responseMsg, asyncToken));
                        }

                        if (asyncTokenItem.AsyncToken != null)
                        {
                            bool needPutToTheQueue = false;
                            try
                            {
                                lock (this.responsesWithoutAsyncTokenTable)
                                {
                                    this.responsesWithoutAsyncTokenTable.Remove(asyncToken.PersistId);
                                }

                                needPutToTheQueue = true;

                                lock (this.requestsAsyncTokenTable)
                                {
                                    this.requestsAsyncTokenTable.Remove(asyncToken.PersistId);
                                }
                            }
                            catch (Exception e)
                            {
                                if (needPutToTheQueue)
                                {
                                    BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PutResponseAsync: remove the request async token from the table failed, the exception: {0}", e);
                                }
                                else
                                {
                                    // in case the reponse message is persisted by another thread.
                                    BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PutResponseAsync: remove the response from the responses without async table fail, the exception: {0}", e);
                                }
                            }

                            if (needPutToTheQueue)
                            {
                                asyncToken.AsyncToken = asyncTokenItem.AsyncToken;
                                asyncToken.Queue.PutResponseAsync(responseMsg, requestItem);
                            }
                            else
                            {
                                BrokerTracing.TraceWarning(
                                    "[BrokerQueueDispatcher] .PutResponseAsync: Don't put response back because needPutToTheQueue=false. AsyncToken.PersistId={0}, requestItem id: {1}, response id:{2}",
                                    asyncToken.PersistId,
                                    requestItem?.Message?.Headers?.MessageId,
                                    responseMsg?.Headers?.MessageId);
                            }
                        }
                        else
                        {
                            // the request item is processed and its response is returned, but its async token is unknown yet.  At this point, as corresponding DispatcherAsyncToken item is
                            // already put into responsesWithoutAsyncTokenTable, the request item itself is of no use now. so dispose it.
                            BrokerTracing.TraceInfo(
                                "[BrokerQueueDispatcher] .PutResponseAsync: Dispose requestItem id: {0}, response id:{1}",
                                requestItem?.Message?.Headers?.MessageId,
                                responseMsg?.Headers?.MessageId);

                            requestItem.Dispose();
                        }
                    }
                }
                else
                {
                    BrokerTracing.TraceError("[BrokerQueueDispatcher] .PutResponseAsync: can not find the async token.");
                }
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError("[BrokerQueueDispatcher] .PutResponseAsync: unkown exception, {0}", e);
            }
        }