How can I configure queues for the scheduling service in our application? I see a generate queues button, but not an add button.
There are several options to configure in the configuration file, this is how this part of the file typically looks like:
<add key="MaximumThreadsTotal" value="" />
<add key="MaximumThreadsPerApplication" value="" />
<add key="MaximumThreadsPerQueue" value="background|2" />
<add key="MaximumThreadsPerPool" value="workflow|4|1" />
The first specifies the maximum number of threads/cores for the entire scheduling service; if empty, it is the number of cores minus 1.
The second specifies the maximum number of threads/cores an application may use; if empty, it is MaximumThreadsTotal minus 1.
The third specifies the maximum number of threads/cores a queue may use. Format: queue_name|number_of_threads_per_queue.
The fourth specifies the maximum number of threads/cores and number of queues for a pool. Format: pool_name|number_of_queues|number_of_threads_per_queue.
Example calculation with the above configuration:
The server has 4 cores.
Then MaximumThreadsTotal is 3.
And MaximumThreadsPerApplication is 2.
The maximum number of cores available for the scheduing service is therefore Max machine cores -1. There will always be 1 core left available for IIS.
There are 2 queues with limitations:
- The background queue (depending on configuration). In the example, it is limited to 2 threads.
- The workflow queue: only 1 task may run at a time.
Queues do not have a preference for a core. But a queue always uses only one core at a time. The processes within Novulo are single-threaded. The advantage of different queues is that multiple tasks can run simultaneously.
And then you also come to the point of how the scheduling service determines which task will be executed:
A continuous process runs that checks per application if something can be executed. For this, it first determines if the application is at its limit. It looks at all tasks of all applications (active or inactive) that are running or stopping. If that is >= MaximumThreadsTotal, then it is at its limit, and nothing will be executed. If the application is inactive, it moves on to the next application.
Then it looks at which task should be executed for the application. First, it checks if the application is at its limit. If so, it moves on to the next application. If not, it checks per queue which task should be executed. If a ‘blocking’ task is running in that queue, it moves on to the next queue. And as it appears, the application task is blocking. So, if a task is running in a queue, it moves on to the next queue.
If the queue is at its limit, it moves on to the next queue. If not, it determines which task should be executed based on priority. The priorities can be limited per queue, but in practice, I don’t think this is used. So, it takes the priority assigned when the task is queued. For tasks with ‘Low’ priority that have been in the queue for more than an hour, the priority is set to normal so that they will eventually be executed.
When adding a scheduled task to your application, you have the possibility to specify a queue name. This will then be added as a queue, if not already present.
When, on the Scheduling service - Queues overview the Refresh queues button is clicked, the new queue will be added, but only once the scheduled task has been triggered.
A queue can have any name, which will be set in the component when configuring a task, p/e a background task could be in an ‘invoices’ queue or just in the ‘background’ queue. Keep in mind that queues do not have priority over each other, so if a task is dependent on something else, plan how to manage timing issues.
Here you can set the queue name for the background process. It will be ‘background’ if left empty.
Workflows, as stated in the example by Stefan, are configured that only one taks can run at a time, to prevent timing issues where something dependant on something else would run before the other task by ensuring they are in the same queue.