Exemple #1
0
        /// <summary>
        /// Try to begin receive messages
        /// </summary>
        /// <param name="ccs">indicating the channel and the client</param>
        /// <returns>if the operation completed synchronously</returns>
        protected override bool TryToBeginReceive(ChannelClientState state)
        {
            T            channel = (T)((ChannelClientState)state).Channel;
            IAsyncResult ar      = null;

            try
            {
                ar = channel.BeginReceiveRequest(this.receiveRequest, state);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[RequestReplyFrontEnd] Exception throwed while begin receive messages: {0}", e);

                // Channel must be in falted state
                lock (channel)
                {
                    if (channel.State == CommunicationState.Faulted)
                    {
                        BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[RequestReplyFrontEnd] About the channel.");

                        // About the falted channel
                        channel.Abort();
                        return(false);
                    }
                }
            }

            return(ar.CompletedSynchronously && channel.State == CommunicationState.Opened);
        }
Exemple #2
0
        /// <summary>
        /// Triggers for queue events
        /// </summary>
        /// <param name="eventId">indicating the event id</param>
        /// <param name="eventArgs">indicating the event args</param>
        private void Queue_OnEvent(BrokerQueueEventId eventId, EventArgs eventArgs)
        {
            if (eventId == BrokerQueueEventId.AllRequestsProcessed)
            {
                // Handle the event in a seperate thread to avoid potential deadlock
                ThreadPool.QueueUserWorkItem(
                    new ThreadHelper <object>(new WaitCallback(this.OnAllRequestsProcessed)).CallbackRoot
                    );
            }
            else if (eventId == BrokerQueueEventId.AllResponesDispatched ||
                     (this.sharedData.SessionFailed && eventId == BrokerQueueEventId.AvailableResponsesDispatched))
            {
                if (eventId == BrokerQueueEventId.AvailableResponsesDispatched)
                {
                    BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerClient] Client {0}: All available responses dispatched, send EndOfResponse message", this.clientId);
                }
                else
                {
                    BrokerTracing.EtwTrace.LogBrokerClientAllResponseDispatched(this.sharedData.BrokerInfo.SessionId, this.clientId);
                }

                if (this.responsesClient != null)
                {
                    this.responsesClient.EndOfResponses(eventId, (ResponseEventArgs)eventArgs);
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Open the frontend
        /// </summary>
        public override void Open()
        {
            try
            {
                this.listener.Open();
            }
            catch (CommunicationException ce)
            {
                BrokerTracing.TraceEvent(TraceEventType.Critical, 0, "[RequestReplyFrontEnd] Exception throwed while opening the listener: {0}", ce);
                this.listener.Abort();
                ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_OpenFrontEndFailed, SR.OpenFrontEndFailed, ce.Message);
            }

            // For session channel, we will try to accept multi channels
            // For nonsession channel, we will only accept one channel
            if (typeof(T) == typeof(IReplySessionChannel))
            {
                for (int i = 0; i < magicNumber; i++)
                {
                    this.listener.BeginAcceptChannel(this.acceptChannel, null);
                }
            }
            else
            {
                // T is IReplyChannel
                this.listener.BeginAcceptChannel(this.acceptChannel, null);
            }
        }
Exemple #4
0
        /// <summary>
        /// For Java to pull the responses
        /// </summary>
        /// <param name="action">indicating the action</param>
        /// <param name="position">indicating the position</param>
        /// <param name="count">indicating the count</param>
        /// <param name="clientId">indicating the client id</param>
        /// <returns>returns the responses messages</returns>
        public BrokerResponseMessages PullResponses(string action, GetResponsePosition position, int count, string clientId)
        {
            try
            {
                ParamCheckUtility.ThrowIfOutofRange(count <= 0, "count");
                ParamCheckUtility.ThrowIfNull(clientId, "clientId");
                ParamCheckUtility.ThrowIfTooLong(clientId.Length, "clientId", Constant.MaxClientIdLength, SR.ClientIdTooLong);
                ParamCheckUtility.ThrowIfNotMatchRegex(ParamCheckUtility.ClientIdValid, clientId, "clientId", SR.InvalidClientId);

                BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerController] PullResponses: Action = {0}, Position = {1}, Count = {2}", action, position, count);
                this.ThrowIfDisposed();
                this.CheckAuth();

                #region Debug Failure Test
                SimulateFailure.FailOperation(1);
                #endregion

                return(this.GetClient(clientId).PullResponses(action, position, count, GetMessageVersion()));
            }
            catch (Exception e)
            {
                BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerController] PullResponses Failed: {0}", e);
                throw TranslateException(e);
            }
        }
Exemple #5
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);
            }
        }
Exemple #6
0
        /// <summary>
        /// Try to begin receive messages
        /// </summary>
        /// <param name="ccs">indicating the channel and the client</param>
        /// <returns>if the operation completed synchronously</returns>
        protected override bool TryToBeginReceive(ChannelClientState ccs)
        {
            IDuplexSessionChannel channel = (IDuplexSessionChannel)ccs.Channel;
            BrokerClient          client  = ccs.Client;
            IAsyncResult          ar      = null;

            try
            {
                ar = channel.BeginReceive(this.receiveRequest, ccs);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[DuplexFrontEnd] Exception throwed while begin receive messages: {0}", e);

                // Channel must be in falted state
                lock (channel)
                {
                    if (channel.State == CommunicationState.Faulted)
                    {
                        BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[DuplexFrontEnd] About the channel.");
                        this.FrontendDisconnect(channel, client);

                        // About the falted channel
                        channel.Abort();
                    }
                }

                return(false);
            }

            return(ar.CompletedSynchronously && channel.State == CommunicationState.Opened);
        }
Exemple #7
0
        /// <summary>
        /// Stop throttling
        /// </summary>
        private void StopThrottling(object sender, EventArgs args)
        {
            if (Interlocked.CompareExchange(ref this.throttling, 0, 1) == 1)
            {
                BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[FrontEndBase] Stop throttling");
                this.throttlingWaitHandle.Set();

                Queue <ChannelClientState> callbackQueue = null;

                if (this.callbackStateQueue.Count > 0)
                {
                    lock (this.callbackStateQueueLock)
                    {
                        if (this.callbackStateQueue.Count > 0)
                        {
                            callbackQueue           = this.callbackStateQueue;
                            this.callbackStateQueue = new Queue <ChannelClientState>();
                        }
                    }
                }

                if (callbackQueue != null)
                {
                    while (callbackQueue.Count > 0)
                    {
                        Task.Run(() => this.tryToReceiveRequestCallback(callbackQueue.Dequeue()));
                    }
                }
            }
        }
Exemple #8
0
        /// <summary>
        /// BrokerQueueCallback root method
        /// </summary>
        /// <param name="item">indicating the broker queue item</param>
        /// <param name="state">indicating the state</param>
        public void CallbackRoot(BrokerQueueItem item, object state)
        {
            if (!this.refObj.IncreaseCount())
            {
                throw new ObjectDisposedException("dispatcher");
            }

            try
            {
                this.brokerQueueCallback(item, state);
            }
            finally
            {
                try
                {
                    this.refObj.DecreaseCount();
                }
                catch (ThreadAbortException)
                {
                }
                catch (AppDomainUnloadedException)
                {
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceEvent(TraceEventType.Critical, 0, "[ReferencedThreadHelper] Exception catched while disposing the object: {0}", e);
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// Init the broker queue
        /// </summary>
        /// <param name="sharedData">indicating the shared data</param>
        /// <param name="clientInfo">output the client info</param>
        /// <returns>returns the broker queue factory</returns>
        private static BrokerQueueFactory InitBrokerQueue(SharedData sharedData, out ClientInfo[] clientInfo)
        {
            BrokerQueueFactory result;

            // Create a durable broker queue if durable is required
            if (sharedData.BrokerInfo.Durable)
            {
                result = new BrokerQueueFactory("AzureQueue", sharedData);
            }
            else
            {
                result = new BrokerQueueFactory(null, sharedData);
            }

            clientInfo = result.AllClientInfos;
            BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[BrokerEntry] Get client id list count: {0}", clientInfo.Length);

            if (clientInfo.Length != 0 && !sharedData.BrokerInfo.Attached)
            {
                throw new BrokerQueueException((int)BrokerQueueErrorCode.E_BQ_CREATE_BROKER_FAIL_EXISTING_BROKER_QUEUE, "Create a broker with an existing broker queue is not allowed.");
            }

            // set persist version
            BrokerQueueItem.PersistVersion = sharedData.BrokerInfo.PersistVersion;

            return(result);
        }
Exemple #10
0
        /// <summary>
        /// Create a IService instance with specified index.
        /// </summary>
        /// <param name="getNextRequest">
        /// trigger the client to retrieve next request
        /// </param>
        /// <param name="clientIndex">
        /// index of the client
        /// </param>
        public virtual async Task CreateClientAsync(bool getNextRequest, int clientIndex)
        {
            if (this.IServiceClient != null)
            {
                BrokerTracing.TraceWarning(
                    BrokerTracing.GenerateTraceString(
                        "RequestSender",
                        "CreateClientAsync",
                        this.TaskId,
                        clientIndex,
                        this.IServiceClient.ToString(),
                        string.Empty,
                        "Closed former client proxy."));

                this.CloseClient();
            }

            try
            {
                await this.CreateClientAsync().ConfigureAwait(false);

                BrokerTracing.TraceVerbose(
                    BrokerTracing.GenerateTraceString(
                        "RequestSender",
                        "CreateClientAsync",
                        this.TaskId,
                        clientIndex,
                        this.IServiceClient.ToString(),
                        string.Empty,
                        "Created a new client."));

                this.Dispatcher.PassBindingFlags[clientIndex] = true;

                GetNextRequestState state = null;

                if (getNextRequest)
                {
                    state = new GetNextRequestState(this.Dispatcher.GetNextRequest, clientIndex);
                }

                this.StartClient(state);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceEvent(
                    TraceEventType.Error,
                    0,
                    "[RequestSender] .CreateClientAsync: ID = {0}, init client failed: {1}",
                    this.TaskId,
                    e);

                if (this.IServiceClient != null)
                {
                    this.CloseClient();
                }

                this.Dispatcher.CloseThis();
            }
        }
Exemple #11
0
 /// <summary>
 /// Start throttling
 /// </summary>
 private void StartThrottling(object sender, EventArgs args)
 {
     if (Interlocked.CompareExchange(ref this.throttling, 1, 0) == 0)
     {
         BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[FrontEndBase] Start throttling");
         this.throttlingWaitHandle.Reset();
     }
 }
Exemple #12
0
 /// <summary>
 /// Create a new instance of the ServiceClient class.
 /// </summary>
 /// <param name="binding">binding information</param>
 /// <param name="remoteAddress">remote address</param>
 public ServiceClient(Binding binding, EndpointAddress remoteAddress)
     : base(binding, remoteAddress)
 {
     BrokerTracing.TraceEvent(
         TraceEventType.Verbose,
         0,
         "[ServiceClient] In constructor, client id {0}, IsHA = {1}",
         this.guid,
         BrokerIdentity.IsHAMode);
 }
Exemple #13
0
        /// <summary>
        /// Close the instance, primarily the underlying communictaion object.
        /// </summary>
        public void AsyncClose()
        {
            BrokerTracing.TraceEvent(
                TraceEventType.Verbose,
                0,
                "[ServiceClient].AsyncClose: Will close the client, client id {0}",
                this.guid);

            Utility.AsyncCloseICommunicationObject(this);
        }
Exemple #14
0
        /// <summary>
        /// Build the frontend
        /// </summary>
        /// <param name="sharedData">indicating the shared data</param>
        /// <param name="observer">indicating the broker observer</param>
        /// <param name="clientManager">indicating the client manager</param>
        /// <param name="brokerAuth">indicating the broker authorization</param>
        /// <param name="bindings">indicating the bindings</param>
        /// <param name="azureQueueProxy">indicating the Azure storage proxy</param>
        /// <returns>frontend result</returns>
        public static FrontendResult BuildFrontEnd(SharedData sharedData, BrokerObserver observer, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, BindingsSection bindings, AzureQueueProxy azureQueueProxy)
        {
            FrontendResult result = new FrontendResult();

            // Bug 9514: Do not open frontend for inprocess broker
            if (sharedData.StartInfo.UseInprocessBroker)
            {
                return(result);
            }

            bool flag = false;

            // Open frontend for different scheme

            // TODO: Separate HTTP frontend and Queue frontend
            if (azureQueueProxy != null)
            {
                flag = true;
                result.SetFrontendInfo(BuildHttpFrontend(sharedData, observer, clientManager, brokerAuth, bindings, azureQueueProxy), TransportScheme.Http);
            }
            else
            {
                if ((sharedData.StartInfo.TransportScheme & TransportScheme.Custom) == TransportScheme.Custom)
                {
                    flag = true;
                    result.SetFrontendInfo(BuildCustomFrontend(sharedData, observer, clientManager, brokerAuth, bindings), TransportScheme.Custom);
                }

                if ((sharedData.StartInfo.TransportScheme & TransportScheme.Http) == TransportScheme.Http)
                {
                    flag = true;
                    result.SetFrontendInfo(BuildHttpFrontend(sharedData, observer, clientManager, brokerAuth, bindings, azureQueueProxy), TransportScheme.Http);
                }

                if ((sharedData.StartInfo.TransportScheme & TransportScheme.NetTcp) == TransportScheme.NetTcp)
                {
                    flag = true;
                    result.SetFrontendInfo(BuildNetTcpFrontend(sharedData, observer, clientManager, brokerAuth, bindings), TransportScheme.NetTcp);
                }

                if ((sharedData.StartInfo.TransportScheme & TransportScheme.NetHttp) == TransportScheme.NetHttp)
                {
                    flag = true;
                    result.SetFrontendInfo(BuildNetHttpFrontend(sharedData, observer, clientManager, brokerAuth, bindings), TransportScheme.NetHttp);
                }
            }

            if (!flag)
            {
                BrokerTracing.TraceEvent(TraceEventType.Critical, 0, "[FrontEndBuilder] Invalid transport scheme: {0}", sharedData.StartInfo.TransportScheme);
                ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_NotSupportedTransportScheme, SR.NotSupportedTransportScheme, sharedData.StartInfo.TransportScheme.ToString());
            }

            return(result);
        }
Exemple #15
0
        /// <summary>
        /// Call EndReply when reply sent
        /// </summary>
        /// <param name="ar">async result</param>
        private void ReplySent(IAsyncResult ar)
        {
            RequestContextBase context = (RequestContextBase)ar.AsyncState;

            try
            {
                context.EndReply(ar);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceEvent(TraceEventType.Error, 0, "[FrontEndBase] Exception throwed while sending reply: {0}", e);
            }
        }
Exemple #16
0
        /// <summary>
        /// Indicating the client that frontend disconnected
        /// </summary>
        /// <param name="channel">indicating the channel</param>
        /// <param name="client">indicating the client</param>
        private void FrontendDisconnect(IDuplexSessionChannel channel, BrokerClient client)
        {
            if (client == null)
            {
                BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[DuplexFrontEnd] FrontendDisconnect client == null");
                client = this.GetClientByChannel(channel, null, String.Empty);
            }

            if (client != null)
            {
                BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[DuplexFrontEnd] FrontendDisconnect client != null");
                client.FrontendDisconnected(channel);
            }
        }
Exemple #17
0
        /// <summary>
        /// Handle fatal broker queue exception
        /// </summary>
        /// <param name="sender">indicating the sender</param>
        /// <param name="fatalExceptionEventArgs">indicating the exception</param>
        private void Queue_OnFatalExceptionEvent(object sender, ExceptionEventArgs fatalExceptionEventArgs)
        {
            BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Critical, 0, "Fatal exception encountered. Exception = {0}", fatalExceptionEventArgs.Exception);
            BrokerQueueException bqException = fatalExceptionEventArgs.Exception as BrokerQueueException;

            if (bqException != null && bqException.ErrorCode == (int)BrokerQueueErrorCode.E_BQ_PERSIST_STORAGE_INSUFFICIENT)
            {
                this.monitor.FailServiceJob("Insufficient broker queue storage").GetAwaiter().GetResult();
            }
            else
            {
                BrokerTracing.TraceError("Unknown exception: {0}", fatalExceptionEventArgs);
            }
        }
Exemple #18
0
 /// <summary>
 /// Increase the perf counter
 /// </summary>
 /// <param name="key">indicate the counter key</param>
 /// <param name="delta">indicate the delta</param>
 public static void IncrementPerfCounterBy(BrokerPerformanceCounterKey key, long delta)
 {
     try
     {
         if (delta != 0)
         {
             GetInstance().counters[(int)key].IncrementBy(delta);
         }
     }
     catch (Exception e)
     {
         BrokerTracing.TraceEvent(TraceEventType.Warning, 0, "Exception throwed while updating perf counter: {0}", e);
     }
 }
Exemple #19
0
        /// <summary>
        /// Initializes a new instance of the BrokerEntry class
        /// </summary>
        /// <param name="sessionId">indicating the session id</param>
        public BrokerEntry(string sessionId)
        {
            BrokerTracing.Initialize(sessionId);

            if (SoaHelper.IsSchedulerOnAzure())
            {
                this.nodeMappingData = new NodeMappingData();

                // Start to get node mapping in a ThreadPool thread.
                this.nodeMappingData.GetNodeMapping();
            }

            BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[BrokerEntry] Broker core service launched.");
        }
Exemple #20
0
        /// <summary>
        /// Ask the broker manager to close this broker
        /// </summary>
        /// <param name="suspend">indicating whether to suspend</param>
        internal void UnloadBroker(bool suspend)
        {
            BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[BrokerEntry] Unload broker domain, ID = {0}", this.sharedData.BrokerInfo.SessionId);

            try
            {
                this.Close(!suspend).GetAwaiter().GetResult();
                BrokerTracing.TraceInfo("[BrokerEntry] Self Cleanup: Close succeeded");
            }
            catch (Exception e)
            {
                BrokerTracing.TraceWarning("[BrokerEntry] Self Cleanup: Close failed: {0}", e);
            }
        }
        /// <summary>
        /// Try to begin receive messages
        /// </summary>
        /// <param name="ccs">indicating the channel and the client</param>
        /// <returns>if the operation completed synchronously</returns>
        protected override bool TryToBeginReceive(ChannelClientState state)
        {
            // IAsyncResult ar = new AsyncResult(state);
            IAsyncResult ar = null;

            try
            {
                ar = this.azureQueueProxy.BeginReceiveRequest(this.receiveRequest, state);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[AzureQueueFrontEnd] Exception throwed while begin receive messages: {0}", e);
            }

            return(ar.CompletedSynchronously);
        }
Exemple #22
0
 /// <summary>
 /// Stop the current timeout
 /// </summary>
 public void Stop()
 {
     if (this.info != null)
     {
         BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[TimeoutManager] {0} Timeout stopped", this.name);
         lock (this.lockThis)
         {
             if (this.info != null)
             {
                 this.info          = null;
                 this.lastResetTime = DateTime.Now;
                 this.timer.Change(Timeout.Infinite, Timeout.Infinite);
             }
         }
     }
 }
Exemple #23
0
        /// <summary>
        /// Close the frontend
        /// </summary>
        /// <param name="disposing">indicating whether it is disposing</param>
        protected override void Dispose(bool disposing)
        {
            this.CloseAllChannel();

            try
            {
                this.listener.Close();
            }
            catch (Exception ce)
            {
                BrokerTracing.TraceEvent(TraceEventType.Warning, 0, "[RequestReplyFrontEnd] Exception throwed while closing the listener: {0}", ce);
                this.listener.Abort();
            }

            base.Dispose(disposing);
        }
Exemple #24
0
 /// <summary>
 /// Callback root method
 /// </summary>
 /// <param name="obj">indicating the state</param>
 public void CallbackRoot(T obj)
 {
     try
     {
         this.callbackDelegate.DynamicInvoke(obj);
     }
     catch (ThreadAbortException)
     {
     }
     catch (AppDomainUnloadedException)
     {
     }
     catch (Exception e)
     {
         BrokerTracing.TraceEvent(TraceEventType.Critical, 0, "[ThreadHelper] Exception catched at root: {0}", e);
     }
 }
Exemple #25
0
 /// <summary>
 /// WaitOrTimerCallback root method
 /// </summary>
 /// <param name="state">indicate the state</param>
 /// <param name="timedOut">indicate the timedOut</param>
 public void WaitOrTimerCallbackRoot(object state, bool timedOut)
 {
     try
     {
         this.callbackDelegate.DynamicInvoke(state, timedOut);
     }
     catch (ThreadAbortException)
     {
     }
     catch (AppDomainUnloadedException)
     {
     }
     catch (Exception e)
     {
         BrokerTracing.TraceEvent(TraceEventType.Critical, 0, "[ThreadHelper] Exception catched at root: {0}", e);
     }
 }
Exemple #26
0
        /// <summary>
        /// Register the timeout
        /// If there's another timeout registered before, the timeout will be replaced
        /// </summary>
        /// <param name="span">time span to trigger the timeout</param>
        /// <param name="callback">callback for the timeout</param>
        /// <param name="state">indicate the async state</param>
        public void RegisterTimeout(int span, WaitCallback callback, object state)
        {
            BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[TimeoutManager] {2} Timeout registered: Span = {0}, State = {1}", span, state, this.name);

            // Change the timer to prevent the timer trigger when updating info
            lock (this.lockThis)
            {
                this.timer.Change(Timeout.Infinite, Timeout.Infinite);
                this.info          = new TimeoutInfo();
                this.info.Span     = span;
                this.info.Callback = callback;
                this.info.State    = state;

                this.lastResetTime = DateTime.Now;
                this.timer.Change(span, span);
            }
        }
Exemple #27
0
        /// <summary>
        /// Initializes a new instance of the DispatcherManager class
        /// </summary>
        /// <param name="bindings">indicating the bindings section</param>
        /// <param name="observer">indicating the observer</param>
        /// <param name="queueFactory">indicating the queue factory</param>
        /// <param name="sharedData">indicating the shared data</param>
        /// <param name="frontendResult">indicating the frontend result</param>
        public DispatcherManager(BindingsSection bindings, SharedData sharedData, BrokerObserver observer, ServiceJobMonitorBase monitor, BrokerQueueFactory queueFactory, ITelepathyContext context)
        {
            this.dispatcherDic          = new Dictionary <string, Dispatcher>();
            this.failedDispatcherList   = new List <string>();
            this.blockedDispatcherDic   = new Dictionary <string, DispatcherInfo>();
            this.blockedDispatcherQueue = new Queue <DispatcherInfo>();

            this.sharedData      = sharedData;
            this.observer        = observer;
            this.monitor         = monitor;
            this.queueFactory    = queueFactory;
            this.context         = context;
            this.defaultCapacity = this.sharedData.ServiceConfig.MaxConcurrentCalls;
            this.blockTimeSpan   = TimeSpan.FromMilliseconds(this.sharedData.Config.LoadBalancing.EndpointNotFoundRetryPeriod);
            this.unblockTimer    = new Timer(new ThreadHelper <object>(new TimerCallback(this.CallbackToQueryBlockedDispatcherList)).CallbackRoot, null, -1, -1);

            this.defaultBinding = BindingHelper.GetBackEndBinding(bindings);
            this.isHttp         = this.defaultBinding.CreateBindingElements().Find <HttpTransportBindingElement>() != null;

            // Update binding's maxMessageSize settings with global maxMessageSize if its enabled (> 0)
            int maxMessageSize = sharedData.ServiceConfig.MaxMessageSize;

            if (maxMessageSize > 0)
            {
                BindingHelper.ApplyMaxMessageSize(this.defaultBinding, maxMessageSize);
            }

            // get soa burst protocol info
            this.httpsBurst = sharedData.BrokerInfo.HttpsBurst;
            if (this.httpsBurst)
            {
                this.azureQueueManager = new AzureQueueManager(sharedData.BrokerInfo.SessionId, this.sharedData.BrokerInfo.ClusterName, this.sharedData.BrokerInfo.ClusterId);
            }

            this.supportsMessageDetails = this.defaultBinding.MessageVersion.Addressing != AddressingVersion.None || this.defaultBinding is BasicHttpBinding;
            BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[DispatcherManager] Init backend binding: OperatiomTimeout = {0}, DefaultCapacity = {1}", this.sharedData.Config.LoadBalancing.ServiceOperationTimeout, this.defaultCapacity);
            BrokerTracing.EtwTrace.LogBackendBindingLoaded(
                sharedData.BrokerInfo.SessionId,
                "Backend",
                maxMessageSize,
                this.defaultBinding.ReceiveTimeout.Ticks,
                this.defaultBinding.SendTimeout.Ticks,
                this.defaultBinding.MessageVersion.ToString(),
                this.defaultBinding.Scheme);
        }
        /// <summary>
        /// Create a new ServiceClient instance
        /// </summary>
        protected override async Task CreateClientAsync()
        {
            DateTime start = DateTime.Now;

            // WCF BUG:
            // We need a sync call Open on ClientBase<> to get the correct impersonation context
            // this is a WCF bug, so we create the client on a dedicated thread.
            // If we call it in thread pool thread, it will block the thread pool thread for a while
            // and drops the performance.
            // The code in Service Job Monitor.TaskStateChanged guaranteed the
            // constructor is called in a dedicated thread.

            do
            {
                try
                {
                    this.Client = new ServiceClient(
                        this.BackendBinding,
                        this.EndpointReferenceAddress);
                    await this.Client.InitAsync().ConfigureAwait(false);

                    return;
                }
                catch (EndpointNotFoundException)
                {
                    int timeRemaining = this.ServiceInitializationTimeout - (int)(DateTime.Now - start).TotalMilliseconds;
                    // retry timeout, log error.
                    BrokerTracing.TraceEvent(
                        TraceEventType.Error,
                        0,
                        "[OnPremiseRequestSender].CreateClientAsync, TaskID = {0}, EndpointNotFoundException, timeRemaining {1}",
                        this.TaskId,
                        timeRemaining);

                    if (timeRemaining <= 0)
                    {
                        throw;
                    }
                    else
                    {
                        Thread.Sleep(Math.Min(this.InitEndpointNotFoundWaitPeriod, timeRemaining));
                    }
                }
            }while (true);
        }
Exemple #29
0
        /// <summary>
        /// Open the frontend
        /// </summary>
        public override void Open()
        {
            try
            {
                this.listener.Open();
            }
            catch (Exception e)
            {
                BrokerTracing.TraceEvent(TraceEventType.Critical, 0, "[DuplexFrontEnd] Exception throwed while opening the listener: {0}", e);
                this.listener.Abort();
                ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_OpenFrontEndFailed, SR.OpenFrontEndFailed, e.Message);
            }

            for (int i = 0; i < magicNumber; i++)
            {
                this.listener.BeginAcceptChannel(this.acceptChannel, null);
            }
        }
        /// <summary>
        /// Open the frontend
        /// </summary>
        public override void Open()
        {
            try
            {
                this.azureQueueProxy.Open();

                // Try to receive messages
                for (int i = 0; i < magicNumber; i++)
                {
                    this.TryToBeginReceiveMessagesWithThrottling(new ChannelClientState(null, null));
                }
            }
            catch (Exception e)
            {
                BrokerTracing.TraceEvent(TraceEventType.Critical, 0, "[AzureQueueFrontEnd] Exception throwed while opening the azure queue proxy : {0}", e);
                throw;
            }
        }