Example #1
0
        /// <summary>
        /// Reply the fault message.
        /// </summary>
        /// <param name="callback">the response service callback.</param>
        /// <param name="faultMessage">indicating the fault message</param>
        /// <param name="clientData">the client data.</param>
        private void ReplyFaultMessage(IResponseServiceCallback callback, Message faultMessage, string clientData)
        {
            if (this.callbackChannelDisposed)
            {
                return;
            }

            this.ResetTimeout();

            try
            {
                faultMessage.Headers.Add(MessageHeader.CreateHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS, clientData));
                if (callback is AzureQueueProxy)
                {
                    callback.SendResponse(faultMessage, clientData);
                }
                else
                {
                    callback.SendResponse(faultMessage);
                }
                this.IncreaseResponsesCount();
            }
            catch (ObjectDisposedException)
            {
                this.callbackChannelDisposed = true;
                this.Queue.ResetResponsesCallback();
            }
            catch (Exception e)
            {
                BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerClient] Client {0}: Failed to send fault message, Exception, {1}", this.clientId, e);
            }
        }
Example #2
0
        /// <summary>
        /// reply the end of message to the client.
        /// </summary>
        /// <param name="callback">the response service callback.</param>
        /// <param name="clientData">the client data.</param>
        /// <param name="clientPurged">indicating the client purged flag</param>
        private void ReplyEndOfMessage(IResponseServiceCallback callback, string clientData, EndOfResponsesReason reason)
        {
            if (this.callbackChannelDisposed)
            {
                return;
            }

            BrokerTracing.TraceInfo("[GetResponsesHandler] Client {0}: Send end of response, clientPurged = {1}", this.clientId, reason);
            this.ResetTimeout();
            TypedMessageConverter converter      = TypedMessageConverter.Create(typeof(EndOfResponses), Constant.EndOfMessageAction);
            EndOfResponses        endOfResponses = new EndOfResponses();

            endOfResponses.Count  = this.ResponsesCount;
            endOfResponses.Reason = reason;
            Message eom = converter.ToMessage(endOfResponses, this.Version);

            eom.Headers.Add(MessageHeader.CreateHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS, clientData));
            this.eorReplied = true;
            try
            {
                if (callback is AzureQueueProxy)
                {
                    callback.SendResponse(eom, clientData);
                }
                else
                {
                    callback.SendResponse(eom);
                }
            }
            catch (ObjectDisposedException)
            {
                BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerClient] Client {0}: Send end of response error: communication object is disposed.", this.clientId);
                this.callbackChannelDisposed = true;
                this.Queue.ResetResponsesCallback();
            }
            catch (Exception ce)
            {
                BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerClient] Client {0}: Send end of response error: {1}", this.clientId, ce);

                // Swallow exception
            }
        }
Example #3
0
        /// <summary>
        /// Called when responses arrive from broker response service
        /// </summary>
        /// <param name="message">Response message </param>
        public void SendResponse(Message message)
        {
            if (message == null || message.Headers == null)
            {
                SessionBase.TraceSource.TraceData(TraceEventType.Error, 0, "Null or headerless message received in main callback");
                return;
            }

            if (this.isSchedulerOnAzure)
            {
                // Use heartbeat to avoid being idle 1 minute.
                if (message.Headers.Action == Constant.BrokerHeartbeatAction)
                {
                    return;
                }
            }

            int index = message.Headers.FindHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS);

            if (index != -1)
            {
                string responseCallbackId = message.Headers.GetHeader <string>(index);
                IResponseServiceCallback responseServiceCallback = null;
                bool callbackExists = false;

                lock (this.responseCallbacks)
                {
                    callbackExists = this.responseCallbacks.TryGetValue(responseCallbackId, out responseServiceCallback);
                }

                if (callbackExists)
                {
                    responseServiceCallback.SendResponse(message);
                }
                else
                {
                    SessionBase.TraceSource.TraceInformation("call back {0} doesn't exist. callbacks count: {1}", responseCallbackId, this.responseCallbacks.Count);
                    // Enumerator or async listener exited early so ignore further responses
                }
            }
            else
            {
                SessionBase.TraceSource.TraceData(TraceEventType.Error, 0, "Unexpected message received in main callback - {0}", message.Headers.Action);
            }
        }
Example #4
0
        /// <summary>
        /// Receive response message
        /// </summary>
        /// <param name="item">broker queue item</param>
        /// <param name="asyncState">async state</param>
        private void ReceiveResponse(BrokerQueueItem item, object asyncState)
        {
            if (this.callbackChannelDisposed)
            {
                throw new Exception("Callback channel was disposed");
            }

            this.ResetTimeout();
            BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 0, "[BrokerClient] Client {0}: Receive Response from BrokerQueue", this.clientId);
            object[] objArray = asyncState as object[];
            IResponseServiceCallback callback = (IResponseServiceCallback)objArray[0];
            string  clientData = objArray[1].ToString();
            Message response   = this.ConvertMessage(item.Message);
            int     index      = response.Headers.FindHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS);

            if (index < 0)
            {
                response.Headers.Add(MessageHeader.CreateHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS, clientData));
            }

            Exception exception = null;

            try
            {
                if (callback is AzureQueueProxy)
                {
                    callback.SendResponse(response, clientData);
                }
                else
                {
                    callback.SendResponse(response);
                }
                BrokerTracing.EtwTrace.LogFrontEndResponseSent(this.SharedData.BrokerInfo.SessionId, this.clientId, Utility.GetMessageIdFromResponse(response));
                this.IncreaseResponsesCount();
            }
            catch (ObjectDisposedException e)
            {
                this.callbackChannelDisposed = true;
                exception = new Exception("Callback channel is disposed", e);
                throw exception;
            }
            catch (CommunicationObjectFaultedException e)
            {
                this.callbackChannelDisposed = true;
                exception = new Exception("Callback channel is faulted", e);
                throw exception;
            }
            catch (CommunicationObjectAbortedException e)
            {
                this.callbackChannelDisposed = true;
                exception = new Exception("Callback channel is abroted", e);
                throw exception;
            }
            catch (Exception ce)
            {
                BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerClient] Client {0}: Send back response error: {1}", this.clientId, ce);

                // Reply a fault message indicating failed to send back the response and reply EOR and finish.
                this.ReplyFaultMessage(callback, FrontEndFaultMessage.GenerateFaultMessage(null, MessageVersion.Default, SOAFaultCode.Broker_SendBackResponseFailed, SR.SendBackResponseFailed), clientData);
                this.ReplyEndOfMessage(callback, clientData);
            }
            finally
            {
                // We do not need to lock here because this callback is designed to be
                // triggered by BrokerQueue synchronizely
                if (this.cacheBrokerQueueItem)
                {
                    lock (this.lockCacheItemList)
                    {
                        this.cachedItemList.Add(item);
                    }
                }
                else
                {
                    this.Queue.AckResponse(item, (exception == null));
                }

                if (this.callbackChannelDisposed)
                {
                    this.Queue.ResetResponsesCallback();
                }
            }
        }