Esempio n. 1
0
        /// <summary>
        /// Gets a broker process from the pool
        /// </summary>
        /// <returns>returns a broker process</returns>
        /// <remarks>this method is thread safe</remarks>
        public BrokerProcess GetBrokerProcess()
        {
            // Create a new broker process in another thread
            ThreadPool.QueueUserWorkItem(this.createNewBrokerProcessCallback);
            DateTime st = DateTime.Now;

            while (true)
            {
                if (this.pool.Count > 0)
                {
                    lock (this.pool)
                    {
                        if (this.pool.Count > 0)
                        {
                            // Gets the last process
                            BrokerProcess process = this.pool[this.pool.Count - 1];
                            process.Exited -= this.BrokerProcess_Exited;
                            this.pool.RemoveAt(this.pool.Count - 1);
                            TraceHelper.TraceEvent(TraceEventType.Information, "[BrokerProcessPool] Fetched broker process, PID = {0}", process.Id);
                            return(process);
                        }
                    }
                }

                if (!this.newBrokerProcessReadyEvent.WaitOne(WaitForNewProcessTimeout, false))
                {
                    if ((int)DateTime.Now.Subtract(st).TotalMilliseconds > GetBrokerProcessTimeout)
                    {
                        ThrowHelper.ThrowSessionFault(SOAFaultCode.TimeoutToGetBrokerWorkerProcess, SR.TimeoutToGetBrokerWorkerProcess);
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Create new broker process
        /// </summary>
        private void CreateNewBrokerProcess(object state)
        {
            BrokerProcess process = new BrokerProcess();

            process.Ready  += new EventHandler <BrokerProcessReadyEventArgs>(this.BrokerProcess_Ready);
            process.Exited += new EventHandler(this.BrokerProcess_Exited);
            process.Start();
        }
Esempio n. 3
0
        /// <summary>
        /// Create custom broker process
        /// </summary>
        /// <param name="customBrokerRegistration">indicating the custom broker registration</param>
        /// <returns>returns the broker process object</returns>
        private static BrokerProcess CreateCustomBrokerProcess(CustomBrokerRegistration customBroker)
        {
            BrokerProcess process = new BrokerProcess(customBroker.Executive, customBroker.EnvironmentVariables);

            process.Start();
            process.WaitForReady();
            return(process);
        }
Esempio n. 4
0
        /// <summary>
        /// Event triggered when broker process is ready
        /// </summary>
        /// <param name="sender">indicating the sender</param>
        /// <param name="e">indicating the event args</param>
        private void BrokerProcess_Ready(object sender, BrokerProcessReadyEventArgs e)
        {
            BrokerProcess process = (BrokerProcess)sender;

            Debug.Assert(process != null, "[BrokerProcessPool] Sender should be an instance of BrokerProcess class.");
            if (e.TimedOut)
            {
                TraceHelper.RuntimeTrace.LogBrokerWorkerProcessFailedToInitialize(process.Id);
                int count = Interlocked.Decrement(ref this.currentPoolSize);
                Debug.Assert(count >= 0, "[BrokerProcessPool] Current pool size should always be non-negative.");
                process.Close();
            }
            else
            {
                lock (this.pool)
                {
                    if (this.disposed)
                    {
                        return;
                    }

                    //
                    // Insert into the list in descending order
                    // This way we can always tell which broker process will be used - it will be always the one with lowest pid
                    // I didn't use SortedList because SortedList needs to be unique in key and there might be a chance where old
                    // process died but is not yet removed from the list while a new process with the exact same PID goes into the
                    // list and lead to exception.
                    //
                    int indexToInsert = 0;
                    int id            = process.Id;
                    while (indexToInsert < this.pool.Count)
                    {
                        if (id >= this.pool[indexToInsert].Id)
                        {
                            break;
                        }

                        indexToInsert++;
                    }

                    this.pool.Insert(indexToInsert, process);
                }

                this.newBrokerProcessReadyEvent.Set();
                TraceHelper.RuntimeTrace.LogBrokerWorkerProcessReady(process.Id);

                int count = Interlocked.Increment(ref this.currentPoolSize);
                if (count <= this.poolSize)
                {
                    ThreadPool.QueueUserWorkItem(this.createNewBrokerProcessCallback);
                }
                else
                {
                    Interlocked.Decrement(ref this.currentPoolSize);
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Event triggered when broker process is exited
        /// </summary>
        /// <param name="sender">indicating the sender</param>
        /// <param name="e">indicating the event args</param>
        private void BrokerProcess_Exited(object sender, EventArgs e)
        {
            BrokerProcess process = (BrokerProcess)sender;

            Debug.Assert(process != null, "[BrokerProcessPool] Sender should be an instance of BrokerProcess class.");
            TraceHelper.RuntimeTrace.LogBrokerWorkerProcessFailedToInitialize(process.Id);
            lock (this.pool)
            {
                if (this.disposed)
                {
                    return;
                }

                this.pool.Remove(process);
            }

            int count = Interlocked.Decrement(ref this.currentPoolSize);

            Debug.Assert(count >= 0, "[BrokerProcessPool] Current pool size should always be non-negative.");
        }
Esempio n. 6
0
        /// <summary>
        /// Start broker process
        /// </summary>
        public void StartBroker()
        {
            bool failoverMode = false;

            if (Interlocked.Increment(ref this.retryCount) > 1)
            {
                // Bug 7150: Need to set attach to true when retrying
                failoverMode             = true;
                this.brokerInfo.Attached = true;
            }

            if (this.customBroker == null || String.IsNullOrEmpty(this.customBroker.Executive))
            {
                this.brokerProcess = this.pool.GetBrokerProcess();
            }
            else
            {
                this.brokerProcess = CreateCustomBrokerProcess(this.customBroker);
            }

            // Log a trace mapping broker worker pid to session id.
            TraceHelper.TraceEvent(
                this.sessionId,
                TraceEventType.Information,
                "[BrokerInfo].StartBroker: Init broker worker {0} for session {1}.",
                this.brokerProcess.Id,
                this.sessionId);

            BrokerManagementServiceClient client = this.CreateClient();

            try
            {
                this.result = client.Initialize(this.sessionStartInfo, this.brokerInfo);

                // Set broker's unique id to the initialization result when the process
                // is (re)started.
                this.result.BrokerUniqueId = this.UniqueId;
                this.brokerProcess.Exited += new EventHandler(this.BrokerProcess_Exited);
            }
            catch (Exception e)
            {
                TraceHelper.TraceEvent(this.sessionId, TraceEventType.Error, "[BrokerInfo] Failed to initialize broker: {0}", e.ToString());

                // If in failover mode, close this broker and do not retry anymore
                if (failoverMode)
                {
                    try
                    {
                        this.CloseBroker(true);
                    }
                    catch (Exception ex)
                    {
                        TraceHelper.TraceEvent(TraceEventType.Warning, "[BrokerInfo].StartBroker: Exception {0}", ex);
                    }
                }

                throw;
            }
            finally
            {
                Utility.AsyncCloseICommunicationObject(client);
            }
        }