SIPSorcery.AppServer.DialPlan.DialPlanEngine.MonitorScripts C# (CSharp) Method

MonitorScripts() private method

private MonitorScripts ( ) : void
return void
        private void MonitorScripts()
        {
            try
            {
                while (!StopScriptMonitoring)
                {
                    DialPlanExecutingScript[] killScripts = null;

                    bool lockTaken = false;
                    Monitor.TryEnter(m_runningScripts, 100, ref lockTaken);
                    if (lockTaken)
                    {
                        try
                        {
                            killScripts = (from script in m_runningScripts
                                           where
                                               script.Complete ||
                                               DateTime.Now > script.EndTime ||
                                               DateTime.Now.Subtract(script.StartTime).TotalSeconds > ABSOLUTEMAX_SCRIPTPROCESSING_SECONDS
                                           select script).ToArray();
                        }
                        finally
                        {
                            Monitor.Exit(m_runningScripts);
                        }
                    }
                    else
                    {
                        logger.Warn("Dialplan engine monitoring thread could not acquire a lock on the running scripts list.");
                    }

                    if (killScripts != null)
                    {
                        for (int index = 0; index < killScripts.Length; index++)
                        {
                            DialPlanExecutingScript killScript = killScripts[index];
                            DialPlanContext dialPlanContext = killScript.ExecutingDialPlanContext;

                            if (!killScript.Complete)
                            {
                                killScript.LogDelegate(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Long running dialplan script is being forcefully terminated.", killScript.Owner));
                            }

                            try
                            {
                                if (dialPlanContext != null && !dialPlanContext.IsAnswered)
                                {
                                    // The dialplan script has finished but the client call has not been answered. There could have be an
                                    // error executing the script or the dialplan could have completed without getting an answer.
                                    if (!killScript.ExecutionError.IsNullOrBlank())
                                    {
                                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed without answering and had an execution error message of " + killScript.ExecutionError + ".", killScript.Owner));
                                        dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, killScript.ExecutionError, null);
                                    }
                                    else if (killScript.LastFailureStatus != SIPResponseStatusCodesEnum.None)
                                    {
                                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed without answering and a last failure status of " + killScript.LastFailureStatus + " " + killScript.LastFailureReason + ".", killScript.Owner));
                                        dialPlanContext.CallFailed(killScript.LastFailureStatus, killScript.LastFailureReason, null);
                                    }
                                    else
                                    {
                                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed without answering and with no last failure status.", killScript.Owner));
                                        dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.TemporarilyUnavailable, null, null);
                                    }
                                }
                                else
                                {
                                    FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed with normal clearing.", killScript.Owner));
                                }

                                long gcMemory = GC.GetTotalMemory(false);
                                long physicalMemory = System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64;

                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan finished for " + killScript.Owner + ", gc memory=" + gcMemory + ", physical memory=" + physicalMemory + ", running script count=" + ScriptCount + ".", null));
                            }
                            catch (Exception finallyExcp)
                            {
                                logger.Error("Exception MonitorScripts Kill. " + finallyExcp.Message);
                            }
                            finally
                            {
                                try
                                {
                                    /*if (killScript.DialPlanScriptThread != null && killScript.DialPlanScriptThread.IsAlive)
                                    {
                                        //logger.Debug("Aborting dialplan script thread.");
                                        killScript.DialPlanScriptThread.Abort();
                                    }*/

                                    killScript.StopExecution();
                                }
                                catch (ThreadStateException) { } // This exception is thrown when aborting a thread in a suspended state and is expected behaviour.
                                catch (Exception killExcp)
                                {
                                    logger.Error("Exception MonitorScripts aborting thread (" + killExcp.GetType().ToString() + "). " + killExcp.Message);
                                }

                                lock (m_runningScripts)
                                {
                                    m_runningScripts.Remove(killScript);
                                }
                                logger.Debug("Executing script " + killScript.DialPlanScriptThread.Name + " removed from running scripts list, running script count=" + ScriptCount + ".");
                            }
                        }
                    }

                    Thread.Sleep(500);
                }

                if (StopScriptMonitoring)
                {
                    if (m_runningScripts.Count > 0)
                    {
                        for (int index = 0; index < m_runningScripts.Count; index++)
                        {
                            if (m_runningScripts[index].DialPlanScriptThread != null && m_runningScripts[index].DialPlanScriptThread.IsAlive)
                            {
                                try
                                {
                                    m_runningScripts[index].DialPlanScriptThread.Abort();
                                }
                                catch (Exception finalKill)
                                {
                                    logger.Debug("Exception on script final kill. " + finalKill.Message);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception MonitorScripts. " + excp);
            }
        }