/// <summary>
 /// Creates a background operation manager for a given queue.
 /// </summary>
 /// <param name="vaultApplication">The vault application that contains this background operation manager.</param>
 /// <param name="queueId">The queue Id.</param>
 /// <param name="cancellationTokenSource">The cancellation token source, if cancellation should be supported.</param>
 public TaskQueueBackgroundOperationManager
 (
     VaultApplicationBase vaultApplication,
     CancellationTokenSource cancellationTokenSource = default
 ) : this
     (
         vaultApplication,
         $"{vaultApplication?.GetType()?.FullName?.Replace(".", "-")}-BackgroundOperations",
         cancellationTokenSource
     )
 {
 }
        /// <summary>
        /// Ensures that <see cref="CurrentServer"/> is set correctly.
        /// </summary>
        /// <param name="vaultApplication">The vault application where this code is running.</param>
        internal static void SetCurrentServer(VaultApplicationBase vaultApplication)
        {
            // Sanity.
            if (null == vaultApplication)
            {
                throw new ArgumentNullException(nameof(vaultApplication));
            }

            // Ensure that we have a current server.
            lock (TaskQueueBackgroundOperationManager._lock)
            {
                if (null == TaskQueueBackgroundOperationManager.CurrentServer)
                {
                    TaskQueueBackgroundOperationManager.CurrentServer
                        = vaultApplication
                          .PermanentVault?
                          .GetVaultServerAttachments()?
                          .GetCurrent();
                }
            }
        }
        /// <summary>
        /// Creates a background operation manager for a given queue.
        /// </summary>
        /// <param name="vaultApplication">The vault application that contains this background operation manager.</param>
        /// <param name="queueId">The queue Id.</param>
        /// <param name="cancellationTokenSource">The cancellation token source, if cancellation should be supported.</param>
        public TaskQueueBackgroundOperationManager
        (
            VaultApplicationBase vaultApplication,
            string queueId,
            CancellationTokenSource cancellationTokenSource = default
        )
        {
            // Sanity.
            if (string.IsNullOrWhiteSpace(queueId))
            {
                throw new ArgumentException("The queue id cannot be null or whitespace.", nameof(queueId));
            }

            // Assign.
            this.CancellationTokenSource = cancellationTokenSource;
            this.VaultApplication        = vaultApplication ?? throw new ArgumentNullException(nameof(vaultApplication));
            this.QueueId = queueId;

            // Set up the task processor
            this.TaskProcessor = this
                                 .VaultApplication
                                 .CreateConcurrentTaskProcessor
                                 (
                this.QueueId,
                new Dictionary <string, TaskProcessorJobHandler>
            {
                { TaskQueueBackgroundOperation.TaskTypeId, this.ProcessJobHandler }
            },
                cancellationTokenSource: cancellationTokenSource == null
                                                ? new CancellationTokenSource()
                                                : CancellationTokenSource.CreateLinkedTokenSource(cancellationTokenSource.Token)
                                 );

            // Ensure we have a current server.
            TaskQueueBackgroundOperationManager.SetCurrentServer(vaultApplication);

            // Register the task queues.
            this.TaskProcessor.RegisterTaskQueues();
        }
Example #4
0
        /// <summary>
        /// Creates an instance of <see cref="AppTaskBatchProcessor"/> for
        /// broadcast task processing, using common configuration settings.
        /// </summary>
        /// <param name="vaultApplication">The vault application that this task processor is associated with.</param>
        /// <param name="queueId">The queue Id (must be unique in the vault) that this application is processing.</param>
        /// <param name="taskHandlers">The task Ids and handlers that this processor can handle.</param>
        /// <param name="cancellationToken">The cancellation token used for cancelling ongoing operations.</param>
        /// <param name="maxConcurrentBatches">The maximum concurrent batches (defaults to 5).</param>
        /// <param name="maxConcurrentJobs">The maximum number of concurrent jobs per batch (defaults to 5).</param>
        /// <param name="maxPollingInterval">The maximum interval (in seconds) between polling.</param>
        /// <param name="automaticallyRegisterQueues">If true, automatically calls <see cref="AppTaskBatchProcessor.RegisterTaskQueues"/>.</param>
        /// <param name="automaticallyStartPolling">If true, automatically calls <see cref="TaskQueueManager.EnableTaskPolling"/>.</param>
        /// <param name="vaultExtensionProxyMethodId">The Id of the vault extension method proxy to use for re-broadcasts.</param>
        /// <returns>The broadcast batch processor.</returns>
        public static AppTaskBatchProcessor CreateBroadcastTaskProcessor
        (
            this VaultApplicationBase vaultApplication,
            string queueId,
            Dictionary <string, TaskProcessorJobHandler> taskHandlers,
            int maxConcurrentBatches         = 5,
            int maxConcurrentJobs            = 5,
            int maxPollingInterval           = 10,
            bool automaticallyRegisterQueues = true,
            bool automaticallyStartPolling   = true,
            CancellationTokenSource cancellationTokenSource = default
        )
        {
            // Sanity.
            if (null == vaultApplication)
            {
                throw new ArgumentNullException(nameof(vaultApplication));
            }
            if (string.IsNullOrWhiteSpace(queueId))
            {
                throw new ArgumentException("A queue Id must be provided.", nameof(queueId));
            }
            if (null == taskHandlers)
            {
                throw new ArgumentNullException(nameof(taskHandlers));
            }
            if (taskHandlers.Count == 0)
            {
                throw new ArgumentException("The processor settings must have at least one task handler defined.", nameof(taskHandlers));
            }
            if (taskHandlers.Any(kvp => kvp.Value == null))
            {
                throw new ArgumentException("Task handlers cannot be null.", nameof(taskHandlers));
            }

            // Ensure the integer values are valid.
            if (maxConcurrentBatches <= 0)
            {
                SysUtils.ReportToEventLog
                (
                    "The maximum concurrent batches must be a positive integer; using default.",
                    System.Diagnostics.EventLogEntryType.Warning
                );
                maxConcurrentBatches = 5;
            }
            if (maxConcurrentJobs <= 0)
            {
                SysUtils.ReportToEventLog
                (
                    "The maximum concurrent jobs must be a positive integer; using default.",
                    System.Diagnostics.EventLogEntryType.Warning
                );
                maxConcurrentJobs = 5;
            }
            if (maxPollingInterval <= 0)
            {
                SysUtils.ReportToEventLog
                (
                    "The maximum polling interval must be a positive integer; using default.",
                    System.Diagnostics.EventLogEntryType.Warning
                );
                maxPollingInterval = 10;
            }

            // Create the processor settings.
            var processorSettings = new AppTaskBatchProcessorSettings
            {
                QueueDef = new TaskQueueDef
                {
                    TaskType           = TaskQueueManager.TaskType.BroadcastMessages,
                    Id                 = queueId,
                    ProcessingBehavior = MFTaskQueueProcessingBehavior.MFProcessingBehaviorConcurrent,
                    MaximumPollingIntervalInSeconds = maxPollingInterval,
                    LastBroadcastId = ""
                },
                PermanentVault                  = vaultApplication.PermanentVault,
                MaxConcurrentBatches            = maxConcurrentBatches,
                MaxConcurrentJobs               = maxConcurrentJobs,
                TaskHandlers                    = taskHandlers,
                TaskQueueManager                = vaultApplication.TaskQueueManager,
                EnableAutomaticTaskUpdates      = true,
                DisableAutomaticProgressUpdates = false,
                PollTasksOnJobCompletion        = true,
                VaultExtensionMethodProxyId     = vaultApplication.GetVaultExtensionMethodEventHandlerProxyName()
            };

            // Create the processor.
            var processor = vaultApplication.CreateBroadcastTaskProcessor
                            (
                processorSettings,
                automaticallyRegisterQueues,
                automaticallyStartPolling,
                cancellationTokenSource
                            );

            // Return the processor.
            return(processor);
        }
Example #5
0
        /// <summary>
        /// Creates an instance of <see cref="AppTaskBatchProcessor"/> for
        /// broadcast task processing, using common configuration settings.
        /// </summary>
        /// <param name="vaultApplication">The vault application that this task processor is associated with.</param>
        /// <param name="processorSettings">The settings for the task processor.</param>
        /// <param name="automaticallyRegisterQueues">If true, automatically calls <see cref="AppTaskBatchProcessor.RegisterTaskQueues"/>.</param>
        /// <param name="automaticallyStartPolling">If true, automatically calls <see cref="TaskQueueManager.EnableTaskPolling"/>.</param>
        /// <returns>The broadcast batch processor.</returns>
        public static AppTaskBatchProcessor CreateBroadcastTaskProcessor
        (
            this VaultApplicationBase vaultApplication,
            AppTaskBatchProcessorSettings processorSettings,
            bool automaticallyRegisterQueues = true,
            bool automaticallyStartPolling   = true,
            CancellationTokenSource cancellationTokenSource = default
        )
        {
            // Sanity.
            if (null == vaultApplication)
            {
                throw new ArgumentNullException(nameof(vaultApplication));
            }
            if (null == processorSettings)
            {
                throw new ArgumentNullException(nameof(processorSettings));
            }
            if (processorSettings.QueueDef.TaskType != TaskQueueManager.TaskType.BroadcastMessages)
            {
                throw new ArgumentException("The processor settings queue definition task type must be BroadcastMessages.", nameof(processorSettings));
            }
            if (null == processorSettings.TaskHandlers)
            {
                throw new ArgumentException("The processor settings must have at least one task handler defined.", nameof(processorSettings));
            }
            if (processorSettings.TaskHandlers.Count == 0)
            {
                throw new ArgumentException("The processor settings must have at least one task handler defined.", nameof(processorSettings));
            }
            if (processorSettings.TaskHandlers.Any(kvp => kvp.Value == null))
            {
                throw new ArgumentException("Task handlers cannot be null.", nameof(processorSettings));
            }

            // Ensure the integer values are valid.
            if (processorSettings.MaxConcurrentBatches <= 0)
            {
                SysUtils.ReportToEventLog
                (
                    "The maximum concurrent batches must be a positive integer; using default.",
                    System.Diagnostics.EventLogEntryType.Warning
                );
                processorSettings.MaxConcurrentBatches = 5;
            }
            if (processorSettings.MaxConcurrentJobs <= 0)
            {
                SysUtils.ReportToEventLog
                (
                    "The maximum concurrent jobs must be a positive integer; using default.",
                    System.Diagnostics.EventLogEntryType.Warning
                );
                processorSettings.MaxConcurrentJobs = 5;
            }
            if (processorSettings.QueueDef.MaximumPollingIntervalInSeconds <= 0)
            {
                SysUtils.ReportToEventLog
                (
                    "The maximum polling interval must be a positive integer; using default.",
                    System.Diagnostics.EventLogEntryType.Warning
                );
                processorSettings.QueueDef.MaximumPollingIntervalInSeconds = 10;
            }

            // Create the processor.
            var processor = new AppTaskBatchProcessor
                            (
                processorSettings,
                cancellationTokenSource?.Token ?? default
                            );

            // Should we automatically register the task queues?
            if (automaticallyRegisterQueues)
            {
                processor.RegisterTaskQueues();
            }

            // Enable polling/processing of the queue.
            if (automaticallyStartPolling)
            {
                vaultApplication.TaskQueueManager.EnableTaskPolling(true);
            }

            // Return the processor.
            return(processor);
        }
Example #6
0
        /// <summary>
        /// Creates an instance of <see cref="SequentialTaskProcessor"/> for
        /// sequential task processing, using common configuration settings.
        /// </summary>
        /// <param name="vaultApplication">The vault application this task processor is associated with.</param>
        /// <param name="queueId">The queue Id (must be unique in the vault) that this application is processing.</param>
        /// <param name="taskHandlers">The task Ids and handlers that this processor can handle.</param>
        /// <param name="cancellationTokenSource">The cancellation token source.</param>
        /// <param name="maxPollingInterval">The maximum interval (in seconds) between polling.</param>
        /// <param name="automaticallyRegisterQueues">If true, automatically calls <see cref="AppTaskBatchProcessor.RegisterTaskQueues"/>.</param>
        /// <param name="automaticallyStartPolling">If true, automatically calls <see cref="TaskQueueManager.EnableTaskPolling"/>.</param>
        /// <returns>The sequential batch processor.</returns>
        public static SequentialTaskProcessor CreateSequentialTaskProcessor
        (
            this VaultApplicationBase vaultApplication,
            string queueId,
            Dictionary <string, TaskProcessorJobHandler> taskHandlers,
            int maxPollingInterval             = 10,
            bool automaticallyRegisterQueues   = true,
            bool automaticallyStartPolling     = true,
            string vaultExtensionProxyMethodId = null,
            CancellationTokenSource cancellationTokenSource = default
        )
        {
            // Sanity.
            if (null == vaultApplication)
            {
                throw new ArgumentNullException(nameof(vaultApplication));
            }
            if (string.IsNullOrWhiteSpace(queueId))
            {
                throw new ArgumentException("A queue Id must be provided.", nameof(queueId));
            }
            if (null == taskHandlers)
            {
                throw new ArgumentNullException(nameof(taskHandlers));
            }
            if (taskHandlers.Count == 0)
            {
                throw new ArgumentException("No task handlers were registered.", nameof(taskHandlers));
            }
            if (taskHandlers.Count == 0)
            {
                throw new ArgumentException("No task handlers were registered.", nameof(taskHandlers));
            }
            if (taskHandlers.Any(kvp => kvp.Value == null))
            {
                throw new ArgumentException("Task handlers cannot be null.", nameof(taskHandlers));
            }

            // Ensure the integer values are valid.
            if (maxPollingInterval <= 0)
            {
                SysUtils.ReportToEventLog
                (
                    "The maximum polling interval must be a positive integer; using default.",
                    System.Diagnostics.EventLogEntryType.Warning
                );
                maxPollingInterval = 10;
            }

            // Create the processor settings.
            var processorSettings = new AppTaskProcessorSettings
            {
                PollTasksOnJobCompletion   = true,
                MaxConcurrentJobs          = 1,        // Always 1 for a sequential task processor.
                PermanentVault             = vaultApplication.PermanentVault,
                EnableAutomaticTaskUpdates = true,
                QueueDef = new TaskQueueDef
                {
                    TaskType           = TaskQueueManager.TaskType.ApplicationTasks,
                    Id                 = queueId,
                    ProcessingBehavior = MFTaskQueueProcessingBehavior.MFProcessingBehaviorSequential,
                    MaximumPollingIntervalInSeconds = maxPollingInterval,
                    LastBroadcastId = ""
                },
                TaskHandlers                = taskHandlers,
                TaskQueueManager            = vaultApplication.TaskQueueManager,
                VaultExtensionMethodProxyId = vaultExtensionProxyMethodId
            };

            // Use the other overload.
            return(vaultApplication.CreateSequentialTaskProcessor
                   (
                       processorSettings,
                       automaticallyRegisterQueues,
                       automaticallyStartPolling,
                       cancellationTokenSource
                   ));
        }