Пример #1
0
        internal JobResultJournalWriter(IObservable <JobResult <TJobInput, TJobOutput> > jobCompletionNotifications,
                                        IJobResultInspector <TJobInput, TJobOutput, TQueuePoison> jobResultInspector,
                                        IDurableJobQueue <TJobInput, TQueuePoison> durableJobQueue,
                                        ILog log,
                                        IScheduler scheduler)
        {
            if (null == durableJobQueue)
            {
                throw new ArgumentNullException("durableJobQueue");
            }
            if (null == jobResultInspector)
            {
                throw new ArgumentNullException("jobResultInspector");
            }
            if (null == jobCompletionNotifications)
            {
                throw new ArgumentNullException("jobCompletionNotifications");
            }

            this._jobCompleted = jobCompletionNotifications
                                 .SubscribeOn(scheduler)
                                 .Subscribe(notification =>
            {
                if (null == notification)
                {
                    log.Error(CultureInfo.CurrentCulture, m => m("Received invalid NULL Notification<JobResult<{0},{1}>>", typeof(TJobInput).Name, typeof(TJobOutput).Name));
                    return;
                }

                var queueAction = jobResultInspector.Inspect(notification);

                if (null == queueAction)
                {
                    log.Error(CultureInfo.CurrentCulture, m => m("Received invalid NULL JobQueueAction<{0}> from Inspect call", typeof(TQueuePoison).Name));
                }
                //no need to check
                else if (queueAction.ActionType == JobQueueActionType.Poison)
                {
                    durableJobQueue.Poison(notification.Input, queueAction.QueuePoison);
                }
                else if (queueAction.ActionType == JobQueueActionType.Complete)
                {
                    durableJobQueue.Complete(notification.Input);
                }
                else
                {
                    log.Error(CultureInfo.CurrentCulture, m => m("Received invalid JobQueueAction<{0}> with JobQueueActionType of Unknown", typeof(TQueuePoison).Name));
                }
            });
        }
Пример #2
0
        /// <summary>	Constructor. </summary>
        /// <remarks>	7/27/2011. </remarks>
        /// <exception cref="ArgumentNullException">	Thrown when the durable job queue is null. </exception>
        /// <param name="durableJobQueue">	IDurableJobQueue to wrap. </param>
        public ObservableDurableJobQueue(IDurableJobQueue <TQueue, TQueuePoison> durableJobQueue)
        {
            if (null == durableJobQueue)
            {
                throw new ArgumentNullException("durableJobQueue");
            }
            var queueType = durableJobQueue.GetType();

            if (queueType.IsGenericType && typeof(ObservableDurableJobQueue <,>).IsAssignableFrom(queueType.GetGenericTypeDefinition()))
            {
                throw new ArgumentException("Incoming queue instance is an ObservableDurableJobQueue.  Nesting not supported.", "durableJobQueue");
            }
            this._durableJobQueue = durableJobQueue;
        }
Пример #3
0
        /// <summary>	Constructor for internal uses only -- specifically. </summary>
        /// <remarks>	7/28/2011. </remarks>
        /// <exception cref="ArgumentNullException">	    Thrown when either the queue or scheduler are null. </exception>
        /// <exception cref="ArgumentOutOfRangeException">	Thrown when the pollingInterval is below the minimum allowed threshold or greater
        /// than the maximum allowed threshold.  Thrown when the items to publish per interval is
        /// less than 1 or greater than the maximum allowed threshold.  </exception>
        /// <param name="durableJobQueue">						Queue of durable jobs. </param>
        /// <param name="maxQueueItemsToPublishPerInterval">	The maximum queue items to publish per interval. </param>
        /// <param name="pollingInterval">						The polling interval. </param>
        /// <param name="scheduler">							The scheduler. </param>
        internal DurableJobQueueMonitor(IDurableJobQueue <TQueue, TQueuePoison> durableJobQueue,
                                        int maxQueueItemsToPublishPerInterval, TimeSpan pollingInterval, IScheduler scheduler)
        {
            if (null == durableJobQueue)
            {
                throw new ArgumentNullException("durableJobQueue");
            }
            if (pollingInterval > DurableJobQueueMonitor.MaximumAllowedPollingInterval)
            {
                throw new ArgumentOutOfRangeException("pollingInterval", String.Format(CultureInfo.CurrentCulture, "must be less than {0:c}", DurableJobQueueMonitor.
                                                                                       MaximumAllowedPollingInterval.ToString()));
            }
            if (pollingInterval < DurableJobQueueMonitor.MinimumAllowedPollingInterval)
            {
                throw new ArgumentOutOfRangeException("pollingInterval", String.Format(CultureInfo.CurrentCulture, "must be at least {0:c}", DurableJobQueueMonitor.
                                                                                       MinimumAllowedPollingInterval));
            }

            if (maxQueueItemsToPublishPerInterval > DurableJobQueueMonitor.MaxAllowedQueueItemsToPublishPerInterval)
            {
                throw new ArgumentOutOfRangeException("maxQueueItemsToPublishPerInterval", String.Format(CultureInfo.CurrentCulture,
                                                                                                         "limited to {0} items to publish per interval", DurableJobQueueMonitor.MaxAllowedQueueItemsToPublishPerInterval));
            }
            if (maxQueueItemsToPublishPerInterval < 1)
            {
                throw new ArgumentOutOfRangeException("maxQueueItemsToPublishPerInterval", "must be at least 1");
            }
            if (null == scheduler)
            {
                throw new ArgumentNullException("scheduler");
            }

            this._durableJobQueue = durableJobQueue;
            this._maxQueueItemsToPublishPerInterval = maxQueueItemsToPublishPerInterval;
            this._pollingInterval = pollingInterval;

            //on first construction, we must move any items out of 'pending' and back into 'queued', in the event of a crash recovery, etc
            durableJobQueue.ResetAllPendingToQueued();

            //fire up our polling on an interval, slurping up all non-nulls from 'queued', to a max of X items, but don't start until connect is called
            _syncRequestPublisher = Observable.Interval(pollingInterval, scheduler)
                                    .SelectMany(interval =>
                                                ReadQueuedItems()
                                                .TakeWhile(request => request.Success)
                                                .Take(maxQueueItemsToPublishPerInterval))
                                    .Select(item => item.Value)
                                    .Publish()
                                    .RefCount();
        }
Пример #4
0
        protected ReadOnlyCollection <TQueue> SlideItemsToPending(IDurableJobQueue <TQueue, TQueuePoison> jobStorage)
        {
            List <TQueue> items = new List <TQueue>();

            while (true)
            {
                var item = jobStorage.NextQueuedItem();
                if (!item.Success)
                {
                    break;
                }

                items.Add(item.Value);
            }

            return(new ReadOnlyCollection <TQueue>(items));
        }
Пример #5
0
        protected void ClearAllQueues(IDurableJobQueue <TQueue, TQueuePoison> storage)
        {
            SlideItemsToPending(storage);
            Assert.Empty(storage.GetQueued());

            foreach (var item in storage.GetPending())
            {
                storage.Complete(item);
            }
            Assert.Empty(storage.GetPending());

            foreach (var item in storage.GetPoisoned())
            {
                storage.Delete(item);
            }
            Assert.Empty(storage.GetPoisoned());
        }
Пример #6
0
 public JobResultJournalWriter(IObservable <JobResult <TJobInput, TJobOutput> > jobCompletionNotifications,
                               IJobResultInspector <TJobInput, TJobOutput, TQueuePoison> jobResultInspector,
                               IDurableJobQueue <TJobInput, TQueuePoison> durableJobQueue)
     : this(jobCompletionNotifications, jobResultInspector, durableJobQueue, LogManager.GetCurrentClassLogger(), LocalScheduler.Default)
 {
 }