示例#1
0
        public WorkQueueProcessor(int numberThreads, ManualResetEvent terminateEvent, string name)
        {
            _terminateEvent = terminateEvent;
            _threadStop     = new ManualResetEvent(false);

            using (IReadContext ctx = PersistentStoreRegistry.GetDefaultStore().OpenReadContext())
            {
                IWorkQueueTypePropertiesEntityBroker  broker   = ctx.GetBroker <IWorkQueueTypePropertiesEntityBroker>();
                WorkQueueTypePropertiesSelectCriteria criteria = new WorkQueueTypePropertiesSelectCriteria();

                IList <WorkQueueTypeProperties> propertiesList = broker.Find(criteria);
                foreach (WorkQueueTypeProperties prop in propertiesList)
                {
                    _propertiesDictionary.Add(prop.WorkQueueTypeEnum, prop);
                }
            }


            _threadPool =
                new WorkQueueThreadPool(numberThreads,
                                        WorkQueueSettings.Instance.PriorityWorkQueueThreadCount,
                                        WorkQueueSettings.Instance.MemoryLimitedWorkQueueThreadCount,
                                        _propertiesDictionary)
            {
                ThreadPoolName = name + " Pool"
            };


            WorkQueueFactoryExtensionPoint ep = new WorkQueueFactoryExtensionPoint();

            object[] factories = ep.CreateExtensions();

            if (factories == null || factories.Length == 0)
            {
                // No extension for the workqueue processor.
                Platform.Log(LogLevel.Warn, "No WorkQueueFactory Extension found.");
            }
            else
            {
                foreach (object obj in factories)
                {
                    IWorkQueueProcessorFactory factory = obj as IWorkQueueProcessorFactory;
                    if (factory != null)
                    {
                        WorkQueueTypeEnum type = factory.GetWorkQueueType();
                        _extensions.Add(type, factory);
                    }
                    else
                    {
                        Platform.Log(LogLevel.Error, "Unexpected incorrect type loaded for extension: {0}",
                                     obj.GetType());
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// The processing thread.
        /// </summary>
        /// <remarks>
        /// This method queries the database for WorkQueue entries to work on, and then uses
        /// a thread pool to process the entries.
        /// </remarks>
        public void Run()
        {
            // Force the alert to be displayed right away, if it happens
            DateTime lastLog = Platform.Time.AddMinutes(-61);

            if (!_threadPool.Active)
            {
                _threadPool.Start();
            }

            Platform.Log(LogLevel.Info, "Work Queue Processor running...");

            while (true)
            {
                if (_stop)
                {
                    return;
                }

                bool threadsAvailable = _threadPool.CanQueueItem;
                bool memoryAvailable  = WorkQueueSettings.Instance.WorkQueueMinimumFreeMemoryMB == 0
                                        ||
                                        SystemResources.GetAvailableMemory(SizeUnits.Megabytes) >
                                        WorkQueueSettings.Instance.WorkQueueMinimumFreeMemoryMB;

                if (threadsAvailable && memoryAvailable)
                {
                    try
                    {
                        Model.WorkQueue queueListItem = GetWorkQueueItem(ServerPlatform.ProcessorId);
                        if (queueListItem == null)
                        {
                            /* No result found, or reach max queue entries for each type */
                            _terminateEvent.WaitOne(WorkQueueSettings.Instance.WorkQueueQueryDelay, false);
                            continue;
                        }

                        if (!_extensions.ContainsKey(queueListItem.WorkQueueTypeEnum))
                        {
                            Platform.Log(LogLevel.Error,
                                         "No extensions loaded for WorkQueue item type: {0}.  Failing item.",
                                         queueListItem.WorkQueueTypeEnum);

                            //Just fail the WorkQueue item, not much else we can do
                            FailQueueItem(queueListItem, "No plugin to handle WorkQueue type: " + queueListItem.WorkQueueTypeEnum);
                            continue;
                        }

                        try
                        {
                            IWorkQueueProcessorFactory factory   = _extensions[queueListItem.WorkQueueTypeEnum];
                            IWorkQueueItemProcessor    processor = factory.GetItemProcessor();

                            // Enqueue the actual processing of the item to the thread pool.
                            _threadPool.Enqueue(processor, queueListItem, ExecuteProcessor);
                        }
                        catch (Exception e)
                        {
                            Platform.Log(LogLevel.Error, e, "Unexpected exception creating WorkQueue processor.");
                            FailQueueItem(queueListItem, "Failure getting WorkQueue processor: " + e.Message);
                            continue;
                        }
                    }
                    catch (Exception e)
                    {
                        // Wait for only 1.5 seconds
                        Platform.Log(LogLevel.Error, e, "Exception occured when processing WorkQueue item.");
                        _terminateEvent.WaitOne(3000, false);
                    }
                }
                else
                {
                    if ((lastLog.AddMinutes(60) < Platform.Time) && !memoryAvailable)
                    {
                        lastLog = Platform.Time;
                        Platform.Log(LogLevel.Error, "Unable to process WorkQueue entries, Minimum memory not available, minimum MB required: {0}, current MB available:{1}",
                                     WorkQueueSettings.Instance.WorkQueueMinimumFreeMemoryMB,
                                     SystemResources.GetAvailableMemory(SizeUnits.Megabytes));

                        ServerPlatform.Alert(AlertCategory.Application, AlertLevel.Critical, "WorkQueue", AlertTypeCodes.NoResources,
                                             null, TimeSpan.Zero,
                                             "Unable to process WorkQueue entries, Minimum memory not available, minimum MB required: {0}, current MB available:{1}",
                                             WorkQueueSettings.Instance.WorkQueueMinimumFreeMemoryMB,
                                             SystemResources.GetAvailableMemory(SizeUnits.Megabytes));
                    }
                    // wait for new opening in the pool or termination
                    WaitHandle.WaitAny(new WaitHandle[] { _threadStop, _terminateEvent }, 3000, false);
                    _threadStop.Reset();
                }
            }
        }