Example #1
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.");
        }
Example #2
0
        /// <summary>
        /// Close the broker
        /// </summary>
        /// <param name="cleanData">indicate whether the broker should clean up the data</param>
        public async Task Close(bool cleanData)
        {
            BrokerTracing.TraceVerbose("[BrokerEntry] Close: Start closing: cleanData = {0}", cleanData);
            this.sharedData.WaitForInitializationComplete();

            if (Interlocked.Increment(ref this.closeFlag) != 1)
            {
                BrokerTracing.TraceInfo("[BrokerEntry] Close race condition detected, quit.");
                return;
            }

            this.cleanData = cleanData;
            int step = 0;

            // Step 1: Close Frontend
            if (this.frontendResult != null)
            {
                for (int i = 0; i < this.frontendResult.ServiceHostList.Length; i++)
                {
                    try
                    {
                        if (this.frontendResult.ServiceHostList[i] != null)
                        {
                            this.frontendResult.ServiceHostList[i].Close(CloseTimeout);
                            BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Close {1} controller frontend succeeded.", ++step, FrontendResult.GetTransportSchemeNameByIndex(i));
                        }
                    }
                    catch (Exception e)
                    {
                        BrokerTracing.TraceWarning("[BrokerEntry] Close: Step {1}: Close {2} controller frontend failed: {0}", e, ++step, FrontendResult.GetTransportSchemeNameByIndex(i));
                    }
                }

                for (int i = 0; i < this.frontendResult.FrontendList.Length; i++)
                {
                    try
                    {
                        if (this.frontendResult.FrontendList[i] != null)
                        {
                            this.frontendResult.FrontendList[i].Close();
                            BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Close {1} frontend succeeded.", ++step, FrontendResult.GetTransportSchemeNameByIndex(i));
                        }
                    }
                    catch (Exception e)
                    {
                        BrokerTracing.TraceWarning("[BrokerEntry] Close: Step {1}: Close {2} frontend failed: {0}", e, ++step, FrontendResult.GetTransportSchemeNameByIndex(i));
                    }
                }
            }

            // Step 2: Close client manager
            List <string> activeClientIdList;

            if (this.clientManager != null)
            {
                activeClientIdList = this.clientManager.GetAllActiveClientIds();
                try
                {
                    if (cleanData)
                    {
                        this.clientManager.DeleteAllQueues();
                    }

                    this.clientManager.Dispose();
                    this.clientManager = null;
                    BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Close client manager succeeded.", ++step);
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Close client manager failed: {1}", ++step, e);
                }
            }
            else
            {
                activeClientIdList = new List <string>();
            }

            //Check the StrategyConfig.WithoutSessionLayer for the close progress.
            //Step 3: Finish the service job if it is needed.
            // We only finish the service job if clean data is required, in other cases, the service job monitor will finish the service job according to the service job life cycle before we enter this stage
            if (this.monitor != null && !SoaCommonConfig.WithoutSessionLayer)
            {
                try
                {
                    if (cleanData)
                    {
                        await this.monitor.FinishServiceJob("Close Session");

                        BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Finish service job succeeded.", ++step);
                    }
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceWarning("[BrokerEntry] Close: Step {0}: Finish service job failed: {1}", ++step, e);
                }
            }

            // Step 4: Close monitor
            if (this.monitor != null)
            {
                try
                {
                    // Update suspended state
                    if (!SoaCommonConfig.WithoutSessionLayer)
                    {
                        await this.monitor.UpdateSuspended(!cleanData);
                    }
                    this.monitor.Close();
                    this.monitor = null;
                    BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Close monitor succeeded.", ++step);
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceWarning("[BrokerEntry] Close: Step {1}: Close monitor failed: {0}", e, ++step);
                }
            }

            // Step 5: Close state manager
            if (this.stateManager != null)
            {
                try
                {
                    this.stateManager.Close();
                    this.stateManager = null;
                    BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Close state manager succeeded.", ++step);
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceWarning("[BrokerEntry] Close: Step {1}: Close state manager failed: {0}", e, ++step);
                }
            }

            // Step 7: Close broker queue
            if (this.brokerQueueFactory != null)
            {
                foreach (ClientInfo clientInfo in this.brokerQueueFactory.AllClientInfos)
                {
                    if (activeClientIdList.Contains(clientInfo.ClientId))
                    {
                        continue;
                    }

                    try
                    {
                        bool        isNewCreated;
                        BrokerQueue queue = this.brokerQueueFactory.GetPersistQueueByClient(clientInfo.ClientId, clientInfo.UserName, out isNewCreated);
                        Debug.Assert(!isNewCreated, "[BrokerEntry] Close: Should only get exsiting persist queue");
                        if (cleanData)
                        {
                            queue.Close();
                        }
                        else
                        {
                            queue.Dispose();
                        }

                        BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Close broker queue {1} succeeded.", ++step, clientInfo.ClientId);
                    }
                    catch (Exception e)
                    {
                        BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Close broker queue {1} failed: {2}", ++step, clientInfo.ClientId, e);
                    }
                }

                try
                {
                    this.brokerQueueFactory.Dispose();
                    this.brokerQueueFactory = null;
                    BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Close broker queue factory succeeded.", ++step);
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceWarning("[BrokerEntry] Close: Step {1}: Close broker queue factory failed: {0}", e, ++step);
                }
            }

            // Step 8: Clean up shared data
            if (this.sharedData != null)
            {
                try
                {
                    this.sharedData.Dispose();
                    this.sharedData = null;
                    BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Close shared data succeeded.", ++step);
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceWarning("[BrokerEntry] Close: Step {0}: Close shared data failed: {1}", ++step, e);
                }
            }

            // Step 9: Dispose node mapping
            if (this.nodeMappingData != null)
            {
                try
                {
                    this.nodeMappingData.Dispose();
                    this.nodeMappingData = null;
                    BrokerTracing.TraceVerbose("[BrokerEntry] Close: Step {0}: Disposing node mapping succeeded.", ++step);
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceWarning("[BrokerEntry] Close: Step {0}: Disposing node mapping failed: {1}", ++step, e);
                }
            }

#if DEBUG
            if (!ReferenceObject.CheckDisposed())
            {
                BrokerTracing.TraceEvent(TraceEventType.Warning, 0, "[BrokerEntry] Reference object not disposed after closing proceduer");
            }
#endif

            BrokerTracing.TraceVerbose("[BrokerEntry] Close finished.");

            if (this.BrokerFinished != null)
            {
                this.BrokerFinished(this, EventArgs.Empty);
            }
        }