public PerformanceMonitor(IRootConfig config, IEnumerable <IWorkItem> appServers, IWorkItem serverManager)
        {
            m_PerfLog = LoggerManager.GetLogger("Performance");

            m_AppServers = appServers.ToArray();

            m_ServerManager = serverManager;

            m_Helper = new ProcessPerformanceCounterHelper(Process.GetCurrentProcess());

            m_TimerInterval    = config.PerformanceDataCollectInterval * 1000;
            m_PerformanceTimer = new Timer(OnPerformanceTimerCallback);
        }
        public void Dispose()
        {
            if (m_PerformanceTimer != null)
            {
                m_PerformanceTimer.Dispose();
                m_PerformanceTimer = null;
            }

            if (m_Helper != null)
            {
                m_Helper.Dispose();
                m_Helper = null;
            }
        }
        protected override IWorkItemBase Start()
        {
            var currentDomain = AppDomain.CurrentDomain;
            var workingDir    = Path.Combine(Path.Combine(currentDomain.BaseDirectory, WorkingDir), Name);

            if (!Directory.Exists(workingDir))
            {
                Directory.CreateDirectory(workingDir);
            }

            m_Locker = new ProcessLocker(workingDir, "instance.lock");

            var portName = string.Format(m_PortNameTemplate, Name, "{0}");

            var process = m_Locker.GetLockedProcess();

            if (process == null)
            {
                var args = string.Join(" ", (new string[] { Name, portName, workingDir }).Select(a => "\"" + a + "\"").ToArray());

                ProcessStartInfo startInfo;

                if (!Platform.IsMono)
                {
                    startInfo = new ProcessStartInfo(m_AgentAssemblyName, args);
                }
                else
                {
                    startInfo = new ProcessStartInfo((Path.DirectorySeparatorChar == '\\' ? "mono.exe" : "mono"), "--runtime=v" + Environment.Version.ToString(2) + " \"" + m_AgentAssemblyName + "\" " + args);
                }

                startInfo.CreateNoWindow         = true;
                startInfo.WindowStyle            = ProcessWindowStyle.Hidden;
                startInfo.WorkingDirectory       = currentDomain.BaseDirectory;
                startInfo.UseShellExecute        = false;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardError  = true;
                startInfo.RedirectStandardInput  = true;

                try
                {
                    m_WorkingProcess = Process.Start(startInfo);
                }
                catch (Exception e)
                {
                    OnExceptionThrown(e);
                    return(null);
                }

                m_WorkingProcess.EnableRaisingEvents = true;
                m_WorkingProcess.ErrorDataReceived  += new DataReceivedEventHandler(m_WorkingProcess_ErrorDataReceived);
                m_WorkingProcess.OutputDataReceived += new DataReceivedEventHandler(m_WorkingProcess_OutputDataReceived);
                m_WorkingProcess.BeginErrorReadLine();
                m_WorkingProcess.BeginOutputReadLine();
            }
            else
            {
                m_WorkingProcess = process;
                m_WorkingProcess.EnableRaisingEvents = true;
            }


            portName    = string.Format(portName, m_WorkingProcess.Id);
            m_ServerTag = portName;

            var remoteUri = string.Format(m_AgentUri, portName);

            IRemoteWorkItem appServer = null;

            if (process == null)
            {
                var startTimeOut = 0;

                int.TryParse(Config.Options.GetValue("startTimeOut", "0"), out startTimeOut);

                if (startTimeOut <= 0)
                {
                    startTimeOut = 10;
                }

                if (!m_ProcessWorkEvent.WaitOne(startTimeOut * 1000))
                {
                    ShutdownProcess();
                    OnExceptionThrown(new Exception("The remote work item was timeout to setup!"));
                    return(null);
                }

                if (!"Ok".Equals(m_ProcessWorkStatus, StringComparison.OrdinalIgnoreCase))
                {
                    OnExceptionThrown(new Exception("The Agent process didn't start successfully!"));
                    return(null);
                }

                appServer = GetRemoteServer(remoteUri);

                if (appServer == null)
                {
                    return(null);
                }

                var bootstrapIpcPort = AppDomain.CurrentDomain.GetData("BootstrapIpcPort") as string;

                if (string.IsNullOrEmpty(bootstrapIpcPort))
                {
                    throw new Exception("The bootstrap's remoting service has not been started.");
                }

                var       ret = false;
                Exception exc = null;

                try
                {
                    var startupConfigFile = Bootstrap.StartupConfigFile;

                    if (!string.IsNullOrEmpty(startupConfigFile))
                    {
                        if (!Path.IsPathRooted(startupConfigFile))
                        {
                            startupConfigFile = Path.Combine(currentDomain.BaseDirectory, startupConfigFile);
                        }
                    }

                    //Setup and then start the remote server instance
                    ret = appServer.Setup(ServerTypeName, "ipc://" + bootstrapIpcPort + "/Bootstrap.rem", currentDomain.BaseDirectory, Config, Factories, startupConfigFile);
                }
                catch (Exception e)
                {
                    exc = e;
                }

                if (!ret)
                {
                    ShutdownProcess();
                    OnExceptionThrown(new Exception("The remote work item failed to setup!", exc));
                    return(null);
                }

                try
                {
                    ret = appServer.Start();
                }
                catch (Exception e)
                {
                    ret = false;
                    exc = e;
                }

                if (!ret)
                {
                    ShutdownProcess();
                    OnExceptionThrown(new Exception("The remote work item failed to start!", exc));
                    return(null);
                }

                m_Locker.SaveLock(m_WorkingProcess);
            }
            else
            {
                appServer = GetRemoteServer(remoteUri);

                if (appServer == null)
                {
                    return(null);
                }
            }

            m_WorkingProcess.Exited   += new EventHandler(m_WorkingProcess_Exited);
            m_PerformanceCounterHelper = new ProcessPerformanceCounterHelper(m_WorkingProcess);

            return(appServer);
        }
 void m_WorkingProcess_Exited(object sender, EventArgs e)
 {
     m_PerformanceCounterHelper = null;
     m_Locker.CleanLock();
     OnStopped();
 }