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)); } }); }
//creation calls should go through the static factory internal MonitoredJobQueue(ObservableDurableJobQueue <TInput, TPoison> durableQueue, Func <TInput, TOutput> jobAction, MonitoredJobQueueConfiguration jobQueueConfiguration, IJobResultInspector <TInput, TOutput, TPoison> resultsInspector, Func <IObservable <TInput>, IObservable <TInput> > notificationFilter, IScheduler scheduler) { //perform null checks only, knowing that additional checks are performed by the new() calls below and will bubble up if (null == durableQueue) { throw new ArgumentNullException("durableQueue"); } if (null == jobAction) { throw new ArgumentNullException("jobAction"); } if (null == jobQueueConfiguration) { throw new ArgumentNullException("jobQueueConfiguration"); } if (null == resultsInspector) { throw new ArgumentNullException("resultsInspector"); } if (null == scheduler) { throw new ArgumentNullException("scheduler"); } if (scheduler == System.Reactive.Concurrency.Scheduler.Immediate) { throw new ArgumentException("Scheduler.Immediate can have horrible side affects, like totally locking up on Subscribe calls, so don't use it", "scheduler"); } this._scheduler = scheduler; this._durableQueue = durableQueue; this._monitor = new DurableJobQueueMonitor <TInput, TPoison>(durableQueue, jobQueueConfiguration.MaxQueueItemsToPublishPerInterval, jobQueueConfiguration.PollingInterval, scheduler); this._jobQueue = new AutoJobExecutionQueue <TInput, TOutput>(scheduler, jobQueueConfiguration.MaxConcurrentJobsToExecute, jobQueueConfiguration.MaxConcurrentJobsToExecute); this._resultJournaler = new JobResultJournalWriter <TInput, TOutput, TPoison>(_jobQueue.WhenJobCompletes, resultsInspector, durableQueue, null, scheduler); //apply a user-specified filter i this._subscription = (null == notificationFilter ? _monitor : notificationFilter(_monitor)) .SubscribeOn(scheduler) .Subscribe(input => _jobQueue.Add(input, jobAction)); }
public JobResultJournalWriter(IObservable <JobResult <TJobInput, TJobOutput> > jobCompletionNotifications, IJobResultInspector <TJobInput, TJobOutput, TQueuePoison> jobResultInspector, IDurableJobQueue <TJobInput, TQueuePoison> durableJobQueue) : this(jobCompletionNotifications, jobResultInspector, durableJobQueue, LogManager.GetCurrentClassLogger(), LocalScheduler.Default) { }