You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-[Queue order and priorities](#queue-order-and-priorities)
21
22
-[Queues specification and performance](#queues-specification-and-performance)
22
23
-[Threads, processes, and signals](#threads-processes-and-signals)
@@ -32,6 +33,7 @@ Solid Queue can be used with SQL databases such as MySQL, PostgreSQL, or SQLite,
32
33
-[Puma plugin](#puma-plugin)
33
34
-[Jobs and transactional integrity](#jobs-and-transactional-integrity)
34
35
-[Recurring tasks](#recurring-tasks)
36
+
-[Scheduling and unscheduling recurring tasks dynamically](#scheduling-and-unscheduling-recurring-tasks-dynamically)
35
37
-[Inspiration](#inspiration)
36
38
-[License](#license)
37
39
@@ -210,7 +212,7 @@ By default, Solid Queue will try to find your configuration under `config/queue.
210
212
bin/jobs -c config/calendar.yml
211
213
```
212
214
213
-
You can also skip all recurring tasks by setting the environment variable `SOLID_QUEUE_SKIP_RECURRING=true`. This is useful for environments like staging, review apps, or development where you don't want any recurring jobs to run. This is equivalent to using the `--skip-recurring` option with `bin/jobs`.
215
+
You can also skip the scheduler process by setting the environment variable `SOLID_QUEUE_SKIP_RECURRING=true`. This is useful for environments like staging, review apps, or development where you don't want any recurring jobs to run. This is equivalent to using the `--skip-recurring` option with `bin/jobs`.
214
216
215
217
This is what this configuration looks like:
216
218
@@ -228,6 +230,10 @@ production:
228
230
threads: 5
229
231
polling_interval: 0.1
230
232
processes: 3
233
+
scheduler:
234
+
dynamic_tasks_enabled: true
235
+
polling_interval: 5
236
+
231
237
```
232
238
233
239
Everything is optional. If no configuration at all is provided, Solid Queue will run with one dispatcher and one worker with default settings. If you want to run only dispatchers or workers, you just need to include that section alone in the configuration. For example, with the following configuration:
@@ -272,6 +278,19 @@ It is recommended to set this value less than or equal to the queue database's c
272
278
- `concurrency_maintenance`: whether the dispatcher will perform the concurrency maintenance work. This is `true` by default, and it's useful if you don't use any [concurrency controls](#concurrency-controls) and want to disable it or if you run multiple dispatchers and want some of them to just dispatch jobs without doing anything else.
273
279
274
280
281
+
### Optional scheduler configuration
282
+
283
+
Optionally, you can configure the scheduler process under the `scheduler` section in your `config/queue.yml` if you'd like to [schedule recurring tasks dynamically](#scheduling-and-unscheduling-recurring-tasks-dynamically).
284
+
285
+
```yaml
286
+
scheduler:
287
+
dynamic_tasks_enabled: true
288
+
polling_interval: 5
289
+
```
290
+
291
+
- `dynamic_tasks_enabled`: whether the scheduler should poll for [dynamically scheduled recurring tasks](#scheduling-and-unscheduling-recurring-tasks-dynamically). This is `false` by default. When enabled, the scheduler will poll the database at the given `polling_interval` to pick up tasks scheduled via `SolidQueue.schedule_recurring_task`.
292
+
- `polling_interval`: how frequently (in seconds) the scheduler checks for dynamic task changes. Defaults to `5`.
293
+
275
294
### Queue order and priorities
276
295
277
296
As mentioned above, if you specify a list of queues for a worker, these will be polled in the order given, such as for the list `real_time,background`, no jobs will be taken from `background` unless there aren't any more jobs waiting in `real_time`.
@@ -463,7 +482,7 @@ class MyJob < ApplicationJob
463
482
- `group`is used to control the concurrency of different job classes together. It defaults to the job class name.
464
483
- `on_conflict` controls behaviour when enqueuing a job that conflicts with the concurrency limits configured. It can be set to one of the following:
465
484
- (default) `:block`: the job is blocked and is dispatched when another job completes and unblocks it, or when the duration expires.
466
-
- `:discard`: the job is discarded. When you choose this option, bear in mind that if a job runs and fails to remove the concurrency lock (or _semaphore_, read below to know more about this), all jobs conflicting with it will be discarded up to the interval defined by `duration` has elapsed.
485
+
- `:discard`: the job is discarded. When you choose this option, bear in mind that if a job runs and fails to remove the concurrency lock (or _semaphore_, read below to know more about this), all jobs conflicting with it will be discarded until the interval defined by `duration` has elapsed.
467
486
468
487
When a job includes these controls, we'll ensure that, at most, the number of jobs (indicated as `to`) that yield the same `key` will be performed concurrently, and this guarantee will last for `duration` for each job enqueued. Note that there's no guarantee about _the order of execution_, only about jobs being performed at the same time (overlapping).
469
488
@@ -473,7 +492,7 @@ Since something can happen that prevents the first job from releasing the semaph
473
492
474
493
It's important to note that after one or more candidate jobs are unblocked (either because a job finishes or because `duration` expires and a semaphore is released), the `duration` timer for the still blocked jobs is reset. This happens indirectly via the expiration time of the semaphore, which is updated.
475
494
476
-
When using `discard` as the behaviour to handle conflicts, you might have jobs discarded for up to the `duration` interval if something happens and a running job fails to release the semaphore.
495
+
When using `discard` as the behaviour to handle conflicts, you might have jobs discarded for until the `duration` interval if something happens and a running job fails to release the semaphore.
477
496
478
497
479
498
For example:
@@ -793,6 +812,38 @@ my_periodic_resque_job:
793
812
794
813
and the job will be enqueued via `perform_later` so it'll run in Resque. However, in this case we won't track any `solid_queue_recurring_execution` record for it and there won't be any guarantees that the job is enqueued only once each time.
795
814
815
+
### Scheduling and unscheduling recurring tasks dynamically
816
+
817
+
You can schedule and unschedule recurring tasks at runtime, without editing the configuration file. To enable this, you need to set `dynamic_tasks_enabled: true` in the `scheduler` section of your `config/queue.yml`, [as explained earlier](#optional-scheduler-configuration).
818
+
819
+
```yaml
820
+
scheduler:
821
+
dynamic_tasks_enabled: true
822
+
```
823
+
824
+
Then you can use the following methods to add recurring tasks dynamically:
825
+
826
+
```ruby
827
+
SolidQueue.schedule_recurring_task(
828
+
"my_dynamic_task",
829
+
class: "MyJob",
830
+
args: [1, 2],
831
+
schedule: "every 10 minutes"
832
+
)
833
+
```
834
+
835
+
This accepts the same options as the YAML configuration: `class`, `args`, `command`, `schedule`, `queue`, `priority`, and `description`.
Only dynamic tasks can be unscheduled at runtime. Attempting to unschedule a static task (defined in `config/recurring.yml`) will raise an `ActiveRecord::RecordNotFound` error.
844
+
845
+
Tasks scheduled like this persist between Solid Queue's restarts and won't stop running until you manually unschedule them.
846
+
796
847
## Inspiration
797
848
798
849
Solid Queue has been inspired by [resque](https://github.com/resque/resque) and [GoodJob](https://github.com/bensheldon/good_job). We recommend checking out these projects as they're great examples from which we've learnt a lot.
0 commit comments