static List <System.Reflection.Assembly> GetAssembliesForAttaching(System.Collections.Specialized.NameValueCollection appSettings, TextWriter logWriter)
        {
            List <System.Reflection.Assembly> assembliesForAttaching = new List <System.Reflection.Assembly>();

            foreach (string assemblyName in appSettings.AllKeys)
            {
                if (appSettings[assemblyName] == "attachAssembly")
                {
                    try
                    {
                        assembliesForAttaching.Add(System.Reflection.Assembly.Load(assemblyName));
                        AspNetLog.Write(logWriter, "loading: " + assemblyName);
                    }
                    // TODO: Исправить - должно падать. Если конфиг сайта неработоспособен - сайт не должен быть работоспособен.
                    catch (Exception ex)
                    {
                        AspNetLog.Write(logWriter, "Error loading assembly: " + assemblyName + " " + ex.ToString());
                        if (appSettings["handlerLoadingPolicy"] == "strict")
                        {
                            throw; // Must fail!
                        }
                    }
                }
            }

            // Добавляем текущую сборку т.к. она содержит типы HTTPServiceRequest, HTTPServiceResponse
            //
            assembliesForAttaching.Add(System.Reflection.Assembly.GetExecutingAssembly());
            return(assembliesForAttaching);
        }
        static AspNetHostEngine()
        {
            System.Collections.Specialized.NameValueCollection appSettings = System.Web.Configuration.WebConfigurationManager.AppSettings;

            TextWriter logWriter = AspNetLog.Open(appSettings);

            _pool = new System.Collections.Concurrent.ConcurrentQueue <AspNetHostEngine>();
            // Загружаем сборки библиотек

            _cachingEnabled = (appSettings["cachingEnabled"] == "true");
            AspNetLog.Write(logWriter, "Start assemblies loading.");
            try
            {
                List <System.Reflection.Assembly> assembliesForAttaching  = GetAssembliesForAttaching(appSettings, logWriter);
                System.Collections.Hashtable      commonModulesForLoading = GetCommonModulesForLoading(appSettings, logWriter);
                List <PropertiesInjectorInfo>     propertiesInjectorsInfo = GetPropertiesInjectors(appSettings, logWriter);

                // Создаем пул экземпляров ядра движка
                int workerThreads         = 0;
                int completionPortThreads = 0;
                int enginesCount          = 0;
                ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);

                if (appSettings["maxThreads"] != null)
                {
                    enginesCount = Convert.ToInt32(appSettings["maxThreads"]);
                }
                else
                {
                    enginesCount = workerThreads;
                }

                if (enginesCount > workerThreads)
                {
                    enginesCount = workerThreads;
                }

                AspNetLog.Write(logWriter, "Max threads running/worker/completionPort: " + enginesCount.ToString() + "/" + workerThreads.ToString() + "/" + completionPortThreads.ToString());

                while (enginesCount > 0)
                {
                    _pool.Enqueue(new AspNetHostEngine(assembliesForAttaching, propertiesInjectorsInfo, commonModulesForLoading));
                    enginesCount--;
                }
            }
            catch (Exception ex)
            {
                AspNetLog.Write(logWriter, ex.ToString());
            }
            AspNetLog.Write(logWriter, "Stop assemblies loading.");
            AspNetLog.Close(logWriter);
        }
示例#3
0
        public static void ExecuteJob(object stateInfo)
        {
            WebBackgroundJob job = (WebBackgroundJob)stateInfo;

            if (job.Key != "" && job.Key != null)
            {
                // Пробуем вставить в таблицу ключей
                //, если вставка неудачна, значит фоновое задание уже выполняется
                if (!jobsKeys.TryAdd(job.Key, job.Key))
                {
                    // Такое значение уже есть в списке, не запускаем задание?
                    throw new RuntimeException("Фоновое задание с таким значением ключа уже выполняется");
                }
            }

            // Заполняем значения работы и вставляем ее в список
            jobs.TryAdd(job.UUID, job);
            job.Begin = DateTime.Now;
            AspNetHostEngine engine = null;

            try
            {
                if (!AspNetHostEngine.Pool.TryDequeue(out engine))
                {
                    throw new RuntimeException("cannot deque engine");
                }

                engine.Engine.EngineInstance.Environment.LoadMemory(MachineInstance.Current);
                engine.CallCommonModuleProcedure(job.MethodName, job.ExecutionParameters);
                job.State = BackgroundJobState.Completed;
                job.ExecutionParameters = null;
            }
            catch (ScriptEngine.ScriptException ex)
            {
                job.ErrorInfo = new ExceptionInfoContext(ex);
                job.State     = BackgroundJobState.Failed;

                System.IO.TextWriter logWriter = AspNetLog.Open();
                AspNetLog.Write(logWriter, "Error executing background job ");
                AspNetLog.Write(logWriter, ex.ToString());
                AspNetLog.Close(logWriter);
            }
            catch (Exception ex)
            {
                job.State = BackgroundJobState.Failed;

                System.IO.TextWriter logWriter = AspNetLog.Open();
                AspNetLog.Write(logWriter, "Error executing background job ");
                AspNetLog.Write(logWriter, ex.ToString());
                AspNetLog.Close(logWriter);
            }
            finally
            {
                job.End = DateTime.Now;
                if (engine != null)
                {
                    AspNetHostEngine.Pool.Enqueue(engine);
                }

                try
                {
                    WebBackgroundJob outjob;
                    jobs.TryRemove(job.UUID, out outjob);
                }
                catch { /* Ничего не делаем*/ }

                try
                {
                    string outStr;
                    if (job.Key != null && job.Key != "")
                    {
                        jobsKeys.TryRemove(job.Key, out outStr);
                    }
                }
                catch { /* Ничего не делаем*/ }
            }
        }
        public void WaitForCompletion(ArrayImpl backgroundJobs, int?timeout = null)
        {
            int  delta     = WebBackgroundJobsManager.CheckInterval;
            long timeoutMs = 1000;

            if (timeout == null)
            {
                delta = 0;
            }
            else
            {
                timeoutMs = (long)(timeout * 1000);
            }

            long current = 0;
            WebBackgroundJobImpl failedJob       = null;
            WebBackgroundJobImpl notCompletedJob = null;

            do
            {
                System.Threading.Thread.Sleep(WebBackgroundJobsManager.CheckInterval);
                current += delta;

                notCompletedJob = null;

                foreach (IValue cj in backgroundJobs)
                {
                    if (((WebBackgroundJobImpl)cj).State == WebBackgroundJobStateImpl.Active)
                    {
                        notCompletedJob = (WebBackgroundJobImpl)cj;
                    }
                    if (((WebBackgroundJobImpl)cj).State == WebBackgroundJobStateImpl.Failed)
                    {
                        failedJob = (WebBackgroundJobImpl)cj;
                        break;
                    }
                }
            } while (current < timeoutMs && notCompletedJob != null && failedJob == null);

            System.IO.TextWriter logWriter;

            if (failedJob != null)
            {
                logWriter = AspNetLog.Open();
                string logStr = failedJob.ErrorInfo.ModuleName + "`n"
                                + failedJob.ErrorInfo.LineNumber + "`n"
                                + failedJob.ErrorInfo.Description + "`n"
                                + failedJob.ErrorInfo.DetailedDescription;
                AspNetLog.Write(logWriter, logStr);
                AspNetLog.Close(logWriter);

                throw (new Exception("Одно или несколько фоновых заданий завершились с ошибкой."));
            }

            if (notCompletedJob == null)
            {
                return;
            }

            string exceptionString = "Timeout expires for job: ";

            exceptionString += "start date: " + notCompletedJob.Begin.ToString() + " ";
            exceptionString += "method: " + notCompletedJob.MethodName + " ";

            if (notCompletedJob.Description != null)
            {
                exceptionString += "description: " + notCompletedJob.Description + " ";
            }
            if (notCompletedJob.Key != null)
            {
                exceptionString += "key: " + notCompletedJob.Description + " ";
            }

            logWriter = AspNetLog.Open();
            AspNetLog.Write(logWriter, exceptionString);
            AspNetLog.Close(logWriter);

            throw (new Exception(exceptionString));
        }
        public void WaitForCompletion(int?timeout = null)
        {
            int  delta     = WebBackgroundJobsManager.CheckInterval;
            long timeoutMs = 1000;

            if (timeout == null)
            {
                delta = 0;
            }
            else
            {
                timeoutMs = (long)(timeout * 1000);
            }

            long current = 0;

            do
            {
                System.Threading.Thread.Sleep(WebBackgroundJobsManager.CheckInterval);
                current += delta;
            } while (current < timeoutMs && State == WebBackgroundJobStateImpl.Active);

            System.IO.TextWriter logWriter;

            if (State == WebBackgroundJobStateImpl.Failed)
            {
                logWriter = AspNetLog.Open();
                string logStr = ErrorInfo.ModuleName + "`n"
                                + ErrorInfo.LineNumber + "`n"
                                + ErrorInfo.Description + "`n"
                                + ErrorInfo.DetailedDescription;
                AspNetLog.Write(logWriter, logStr);
                AspNetLog.Close(logWriter);

                throw (new Exception("Фоновое задание завершились с ошибкой."));
            }

            if (State == WebBackgroundJobStateImpl.Completed)
            {
                return;
            }

            string exceptionString = "Timeout expires for job: ";

            exceptionString += "start date: " + Begin.ToString() + " ";
            exceptionString += "method: " + MethodName + " ";

            if (Description != null)
            {
                exceptionString += "description: " + Description + " ";
            }
            if (Key != null)
            {
                exceptionString += "key: " + Description + " ";
            }

            logWriter = AspNetLog.Open();
            AspNetLog.Write(logWriter, exceptionString);
            AspNetLog.Close(logWriter);

            throw (new Exception(exceptionString));
        }