Example #1
0
        /// <summary>
        /// The actual delegate
        /// </summary>
        /// <param name="processor"></param>
        /// <param name="queueItem"></param>
        private void ExecuteProcessor(IWorkQueueItemProcessor processor, Model.WorkQueue queueItem)
        {
            try
            {
                processor.Process(queueItem);
            }
            catch (Exception e)
            {
                Platform.Log(LogLevel.Error, e,
                             "Unexpected exception when processing WorkQueue item of type {0}.  Failing Queue item. (GUID: {1})",
                             queueItem.WorkQueueTypeEnum,
                             queueItem.GetKey());
                String error = e.InnerException != null ? e.InnerException.Message : e.Message;

                FailQueueItem(queueItem, error);
            }
            finally
            {
                // Signal the parent thread, so it can query again
                _threadStop.Set();

                // Cleanup the processor
                processor.Dispose();
            }
        }
Example #2
0
        /// <summary>
        /// Enqueue a WorkQueue entry for processing.
        /// </summary>
        /// <param name="processor"></param>
        /// <param name="item"></param>
        /// <param name="del"></param>
        public void Enqueue(IWorkQueueItemProcessor processor, Model.WorkQueue item, WorkQueueThreadDelegate del)
        {
            WorkQueueThreadParameter parameter = new WorkQueueThreadParameter(processor, item, del);

            lock (_syncLock)
            {
                if (item.WorkQueuePriorityEnum.Equals(WorkQueuePriorityEnum.High))
                {
                    _highPriorityCount++;
                }
                if (item.WorkQueuePriorityEnum.Equals(WorkQueuePriorityEnum.Stat))
                {
                    _highPriorityCount++;
                }

                WorkQueueTypeProperties prop = _workQueuePropList[item.WorkQueueTypeEnum];
                if (prop.MemoryLimited)
                {
                    _memoryLimitedCount++;
                }

                _totalThreadCount++;

                _queuedItems.Add(parameter);
            }

            Enqueue(parameter, delegate(WorkQueueThreadParameter threadParameter)
            {
                threadParameter.Delegate(threadParameter.Processor, threadParameter.Item);

                QueueItemComplete(threadParameter.Item);
            });
        }
Example #3
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();
                }
            }
        }
Example #4
0
 public WorkQueueThreadParameter(IWorkQueueItemProcessor processor, Model.WorkQueue item, WorkQueueThreadDelegate del)
 {
     _item      = item;
     _processor = processor;
     _del       = del;
 }
Example #5
0
		/// <summary>
		/// The actual delegate 
		/// </summary>
		/// <param name="processor"></param>
		/// <param name="queueItem"></param>
		private void ExecuteProcessor(IWorkQueueItemProcessor processor, Model.WorkQueue queueItem)
		{
			try
			{
				processor.Process(queueItem);
			}
			catch (Exception e)
			{
				Platform.Log(LogLevel.Error, e,
				             "Unexpected exception when processing WorkQueue item of type {0}.  Failing Queue item. (GUID: {1})",
				             queueItem.WorkQueueTypeEnum,
				             queueItem.GetKey());
				String error = e.InnerException != null ? e.InnerException.Message : e.Message;

				FailQueueItem(queueItem, error);
			}
			finally
			{
                // Signal the parent thread, so it can query again
                _threadStop.Set();

                // Cleanup the processor
                processor.Dispose();
			}

		}