solid_queue 0.7.1 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a7234dc4430998648196bf2d3905b66bb85e265c2393121a7c5343fed36b1996
4
- data.tar.gz: 216a0918e29194e6d11fe4bf365183228127f8390658a11ace329523ad41468c
3
+ metadata.gz: '053856cc5d0d234f55fa42184371360bca7278a37130bc4230656c48ac0f8e74'
4
+ data.tar.gz: f31c7c8e48f67874365e788cb301c41e5a3be8dc77f28bf5e848f01645076928
5
5
  SHA512:
6
- metadata.gz: a080aedf20f39940d8c25e8a14628811801b8fd4832fbcb926beecd0d1ce4c694ec8d80b608656f9de80cc8cc69b525f62d4fe7bc7258408aa6d6af62292d4fd
7
- data.tar.gz: 66d24c1bb1c7cb1b9afbcf8a0b667df624dd3f47cea92887fbcd69d93b1832af3c44afb570d1cfb459c37e2b3c163900e0dd2febb067ee9179b4c49514e4b359
6
+ metadata.gz: cdd486cd413c30d10deea24ba32f8f9e06000263a619f0fb175f08695a53f83a55eae56a19aa626e97af1e37a882c16be40441a158569ca06cb3140681414c8e
7
+ data.tar.gz: 1545db515ce86ad1f5e327533be2cfeba19a2b5bb162139dfa40584482a9d1b576775c97d79d4aa6baa5aff36fb3a7579088e9e9ef4852e03f79544fc5a0091e
data/README.md CHANGED
@@ -6,43 +6,52 @@ Besides regular job enqueuing and processing, Solid Queue supports delayed jobs,
6
6
 
7
7
  Solid Queue can be used with SQL databases such as MySQL, PostgreSQL or SQLite, and it leverages the `FOR UPDATE SKIP LOCKED` clause, if available, to avoid blocking and waiting on locks when polling jobs. It relies on Active Job for retries, discarding, error handling, serialization, or delays, and it's compatible with Ruby on Rails multi-threading.
8
8
 
9
- ## Installation and usage
10
- Add this line to your application's Gemfile:
9
+ ## Installation
11
10
 
12
- ```ruby
13
- gem "solid_queue"
14
- ```
11
+ Solid Queue is configured by default in new Rails 8 applications. But if you're running an earlier version, you can add it manually following these steps:
15
12
 
16
- And then execute:
17
- ```bash
18
- $ bundle
19
- ```
13
+ 1. `bundle add solid_queue`
14
+ 2. `bin/rails solid_queue:install`
20
15
 
21
- Or install it yourself as:
22
- ```bash
23
- $ gem install solid_queue
24
- ```
16
+ This will configure Solid Queue as the production Active Job backend, create `config/solid_queue.yml`, and create the `db/queue_schema.rb`.
25
17
 
26
- Now, you need to install the necessary migrations and configure the Active Job's adapter. You can do both at once using the provided generator:
18
+ You will then have to add the configuration for the queue database in `config/database.yml`. If you're using sqlite, it'll look like this:
27
19
 
28
- ```bash
29
- $ bin/rails generate solid_queue:install
20
+ ```yaml
21
+ production:
22
+ primary:
23
+ <<: *default
24
+ database: storage/production.sqlite3
25
+ queue:
26
+ <<: *default
27
+ database: storage/production_queue.sqlite3
28
+ migrations_paths: db/queue_migrate
30
29
  ```
31
30
 
32
- This will set `solid_queue` as the Active Job's adapter in production, and will copy the required migration over to your app.
31
+ ...or if you're using MySQL/PostgreSQL/Trilogy:
33
32
 
34
- Alternatively, you can skip setting the Active Job's adapter with:
35
- ```bash
36
- $ bin/rails generate solid_queue:install --skip_adapter
33
+ ```yaml
34
+ production:
35
+ primary: &primary_production
36
+ <<: *default
37
+ database: app_production
38
+ username: app
39
+ password: <%= ENV["APP_DATABASE_PASSWORD"] %>
40
+ queue:
41
+ <<: *primary_production
42
+ database: app_production_queue
43
+ migrations_paths: db/queue_migrate
37
44
  ```
38
45
 
39
- And set Solid Queue as your Active Job's queue backend manually, in your environment config:
40
- ```ruby
41
- # config/environments/production.rb
42
- config.active_job.queue_adapter = :solid_queue
43
- ```
46
+ Then run `db:prepare` in production to ensure the database is created and the schema is loaded.
47
+
48
+ Now you're ready to start processing jobs by running `bin/jobs` on the server that's doing the work. This will start processing jobs in all queues using the default configuration. See [below](#configuration) to learn more about configuring Solid Queue.
49
+
50
+ For small projects, you can run Solid Queue on the same machine as your webserver. When you're ready to scale, Solid Queue supports horizontal scaling out-of-the-box. You can run Solid Queue on a separate server from your webserver, or even run `bin/jobs` on multiple machines at the same time. Depending on the configuration, you can designate some machines to run only dispatchers or only workers. See the [configuration](#configuration) section for more details on this.
51
+
52
+ ## Incremental adoption
44
53
 
45
- Or you can set only specific jobs to use Solid Queue as their backend if you're migrating from another adapter and want to move jobs progressively:
54
+ If you're planning to adopt Solid Queue incrementally by switching one job at the time, you can do so by leaving the `config.active_job.queue_adapter` set to your old backend, and then set the `queue_adapter` directly in the jobs you're moving:
46
55
 
47
56
  ```ruby
48
57
  # app/jobs/my_job.rb
@@ -52,24 +61,9 @@ class MyJob < ApplicationJob
52
61
  # ...
53
62
  end
54
63
  ```
64
+ ## High performance requirements
55
65
 
56
- Finally, you need to run the migrations:
57
-
58
- ```bash
59
- $ bin/rails db:migrate
60
- ```
61
-
62
- After this, you'll be ready to enqueue jobs using Solid Queue, but you need to start Solid Queue's supervisor to run them. You can use the provided binstub:`
63
- ```bash
64
- $ bin/jobs
65
- ```
66
-
67
- This will start processing jobs in all queues using the default configuration. See [below](#configuration) to learn more about configuring Solid Queue.
68
-
69
- For small projects, you can run Solid Queue on the same machine as your webserver. When you're ready to scale, Solid Queue supports horizontal scaling out-of-the-box. You can run Solid Queue on a separate server from your webserver, or even run `bin/jobs` on multiple machines at the same time. Depending on the configuration, you can designate some machines to run only dispatchers or only workers. See the [configuration](#configuration) section for more details on this.
70
-
71
- ## Requirements
72
- Besides Rails 7.1, Solid Queue works best with MySQL 8+ or PostgreSQL 9.5+, as they support `FOR UPDATE SKIP LOCKED`. You can use it with older versions, but in that case, you might run into lock waits if you run multiple workers for the same queue.
66
+ Solid Queue was designed for the highest throughput when used with MySQL 8+ or PostgreSQL 9.5+, as they support `FOR UPDATE SKIP LOCKED`. You can use it with older versions, but in that case, you might run into lock waits if you run multiple workers for the same queue. You can also use it with SQLite on smaller applications.
73
67
 
74
68
  ## Configuration
75
69
 
@@ -135,8 +129,8 @@ Here's an overview of the different options:
135
129
  - `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.
136
130
  - `recurring_tasks`: a list of recurring tasks the dispatcher will manage. Read more details about this one in the [Recurring tasks](#recurring-tasks) section.
137
131
 
138
-
139
132
  ### Queue order and priorities
133
+
140
134
  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`.
141
135
 
142
136
  Active Job also supports positive integer priorities when enqueuing jobs. In Solid Queue, the smaller the value, the higher the priority. The default is `0`.
@@ -159,54 +153,11 @@ When receiving a `QUIT` signal, if workers still have jobs in-flight, these will
159
153
  If processes have no chance of cleaning up before exiting (e.g. if someone pulls a cable somewhere), in-flight jobs might remain claimed by the processes executing them. Processes send heartbeats, and the supervisor checks and prunes processes with expired heartbeats, which will release any claimed jobs back to their queues. You can configure both the frequency of heartbeats and the threshold to consider a process dead. See the section below for this.
160
154
 
161
155
 
162
- ### Dedicated database configuration
163
-
164
- Solid Queue can be configured to run on a different database than the main application.
165
-
166
- Configure the `connects_to` option in `config/application.rb` or your environment config, with the custom database configuration that will be used in the abstract `SolidQueue::Record` Active Record model.
167
-
168
- ```ruby
169
- # Use a separate DB for Solid Queue
170
- config.solid_queue.connects_to = { database: { writing: :solid_queue_primary, reading: :solid_queue_replica } }
171
- ```
172
-
173
- Add the dedicated database configuration to `config/database.yml`, differentiating between the main app's database and the dedicated `solid_queue` database. Make sure to include the `migrations_paths` for the solid queue database. This is where migration files for Solid Queue tables will reside.
174
-
175
- ```yml
176
- default: &default
177
- adapter: sqlite3
178
- pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
179
- timeout: 5000
180
-
181
- solid_queue: &solid_queue
182
- <<: *default
183
- migrations_paths: db/solid_queue_migrate
184
-
185
- development:
186
- primary:
187
- <<: *default
188
- # ...
189
- solid_queue_primary:
190
- <<: *solid_queue
191
- # ...
192
- solid_queue_replica:
193
- <<: *solid_queue
194
- # ...
195
- ```
196
-
197
- Install migrations and specify the dedicated database name with the `--database` option. This will create the Solid Queue migration files in a separate directory, matching the value provided in `migrations_paths` in `config/database.yml`.
198
-
199
- ```bash
200
- $ bin/rails g solid_queue:install --database solid_queue
201
- ```
202
-
203
- Note: If you've already run the solid queue install command (`bin/rails generate solid_queue:install`) without a `--database` option, the migration files will have already been generated under the primary database's `db/migrate/` directory. You can remove these files and keep the ones generated by the database-specific migration installation above.
156
+ ### Database configuration
204
157
 
205
- Finally, run the migrations:
158
+ You can configure the database used by Solid Queue via the `config.solid_queue.connects_to` option in the `config/application.rb` or `config/environments/production.rb` config files. By default, a single database is used for both writing and reading called `queue` to match the database configuration you set up during the install.
206
159
 
207
- ```bash
208
- $ bin/rails db:migrate
209
- ```
160
+ All the options available to Active Record for multiple databases can be used here.
210
161
 
211
162
  ## Lifecycle hooks
212
163
 
@@ -235,8 +186,8 @@ SolidQueue.on_stop { stop_metrics_server }
235
186
 
236
187
  These can be called several times to add multiple hooks, but it needs to happen before Solid Queue is started. An initializer would be a good place to do this.
237
188
 
238
-
239
189
  ### Other configuration settings
190
+
240
191
  _Note_: The settings in this section should be set in your `config/application.rb` or your environment config like this: `config.solid_queue.silence_polling = true`
241
192
 
242
193
  There are several settings that control how Solid Queue works that you can set as well:
@@ -261,11 +212,13 @@ There are several settings that control how Solid Queue works that you can set a
261
212
  - `enqueue_after_transaction_commit`: whether the job queuing is deferred to after the current Active Record transaction is committed. The default is `false`. [Read more](https://github.com/rails/rails/pull/51426).
262
213
 
263
214
  ## Errors when enqueuing
215
+
264
216
  Solid Queue will raise a `SolidQueue::Job::EnqueueError` for any Active Record errors that happen when enqueuing a job. The reason for not raising `ActiveJob::EnqueueError` is that this one gets handled by Active Job, causing `perform_later` to return `false` and set `job.enqueue_error`, yielding the job to a block that you need to pass to `perform_later`. This works very well for your own jobs, but makes failure very hard to handle for jobs enqueued by Rails or other gems, such as `Turbo::Streams::BroadcastJob` or `ActiveStorage::AnalyzeJob`, because you don't control the call to `perform_later` in that cases.
265
217
 
266
218
  In the case of recurring tasks, if such error is raised when enqueuing the job corresponding to the task, it'll be handled and logged but it won't bubble up.
267
219
 
268
220
  ## Concurrency controls
221
+
269
222
  Solid Queue extends Active Job with concurrency controls, that allows you to limit how many jobs of a certain type or with certain arguments can run at the same time. When limited in this way, jobs will be blocked from running, and they'll stay blocked until another job finishes and unblocks them, or after the set expiry time (concurrency limit's _duration_) elapses. Jobs are never discarded or lost, only blocked.
270
223
 
271
224
  ```ruby
@@ -331,35 +284,15 @@ failed_execution.discard # This will delete the job from the system
331
284
  However, we recommend taking a look at [mission_control-jobs](https://github.com/rails/mission_control-jobs), a dashboard where, among other things, you can examine and retry/discard failed jobs.
332
285
 
333
286
  ## Puma plugin
287
+
334
288
  We provide a Puma plugin if you want to run the Solid Queue's supervisor together with Puma and have Puma monitor and manage it. You just need to add
335
289
  ```ruby
336
290
  plugin :solid_queue
337
291
  ```
338
292
  to your `puma.rb` configuration.
339
293
 
340
-
341
- ## Jobs and transactional integrity
342
- :warning: Having your jobs in the same ACID-compliant database as your application data enables a powerful yet sharp tool: taking advantage of transactional integrity to ensure some action in your app is not committed unless your job is also committed. This can be very powerful and useful, but it can also backfire if you base some of your logic on this behaviour, and in the future, you move to another active job backend, or if you simply move Solid Queue to its own database, and suddenly the behaviour changes under you.
343
-
344
- By default, Solid Queue runs in the same DB as your app, and job enqueuing is _not_ deferred until any ongoing transaction is committed, which means that by default, you'll be taking advantage of this transactional integrity.
345
-
346
- If you prefer not to rely on this, or avoid relying on it unintentionally, you should make sure that:
347
- - You set [`config.active_job.enqueue_after_transaction_commit`](https://edgeguides.rubyonrails.org/configuring.html#config-active-job-enqueue-after-transaction-commit) to `always`, if you're using Rails 7.2+.
348
- - Or, your jobs relying on specific records are always enqueued on [`after_commit` callbacks](https://guides.rubyonrails.org/active_record_callbacks.html#after-commit-and-after-rollback) or otherwise from a place where you're certain that whatever data the job will use has been committed to the database before the job is enqueued.
349
- - Or, you configure a different database for Solid Queue, even if it's the same as your app, ensuring that a different connection on the thread handling requests or running jobs for your app will be used to enqueue jobs. For example:
350
-
351
- ```ruby
352
- class ApplicationRecord < ActiveRecord::Base
353
- self.abstract_class = true
354
-
355
- connects_to database: { writing: :primary, reading: :replica }
356
- ```
357
-
358
- ```ruby
359
- config.solid_queue.connects_to = { database: { writing: :primary, reading: :replica } }
360
- ```
361
-
362
294
  ## Recurring tasks
295
+
363
296
  Solid Queue supports defining recurring tasks that run at specific times in the future, on a regular basis like cron jobs. These are managed by dispatcher processes and as such, they can be defined in the dispatcher's configuration like this:
364
297
  ```yml
365
298
  dispatchers:
data/UPGRADING.md CHANGED
@@ -1,6 +1,9 @@
1
+ # Upgrading to version 0.8.x
2
+ *IMPORTANT*: This version collapsed all migrations into a single `db/queue_schema.rb`, that will use a separate `queue` database. If you're upgrading from a version < 0.6.0, you need to upgrade to 0.6.0 first, ensure all migrations are up-to-date, and then upgrade further.
3
+
1
4
  # Upgrading to version 0.7.x
2
5
 
3
- This version removed the new async mode introduced in version 0.4.0 and introduced a new binstub that can be used to start Solid Queue's supervisor. It includes also a minor migration.
6
+ This version removed the new async mode introduced in version 0.4.0 and introduced a new binstub that can be used to start Solid Queue's supervisor.
4
7
 
5
8
  To install both the binstub `bin/jobs` and the migration, you can just run
6
9
  ```
@@ -5,6 +5,6 @@ Example:
5
5
  bin/rails generate solid_queue:install
6
6
 
7
7
  This will perform the following:
8
- Installs solid_queue migrations
8
+ Adds solid_queue db schema
9
9
  Replaces Active Job's adapter in environment configuration
10
10
  Installs bin/jobs binstub to start the supervisor
@@ -3,33 +3,17 @@
3
3
  class SolidQueue::InstallGenerator < Rails::Generators::Base
4
4
  source_root File.expand_path("templates", __dir__)
5
5
 
6
- class_option :skip_adapter, type: :boolean, default: nil, desc: "Skip setting Solid Queue as the Active Job's adapter"
7
- class_option :database, type: :string, default: nil, desc: "The database to use for migrations, if different from the primary one."
8
-
9
- def add_solid_queue
10
- unless options[:skip_adapter]
11
- if (env_config = Pathname(destination_root).join("config/environments/production.rb")).exist?
12
- say "Setting solid_queue as Active Job's queue adapter"
13
- gsub_file env_config, /(# )?config\.active_job\.queue_adapter\s+=.*/, "config.active_job.queue_adapter = :solid_queue"
14
- end
15
- end
16
-
17
- if File.exist?("config/solid_queue.yml")
18
- say "Skipping sample configuration as config/solid_queue.yml exists"
19
- else
20
- say "Copying sample configuration"
21
- copy_file "config.yml", "config/solid_queue.yml"
22
- end
23
-
24
- say "Copying binstub"
25
- copy_file "jobs", "bin/jobs"
6
+ def copy_files
7
+ template "config/solid_queue.yml"
8
+ template "db/queue_schema.rb"
9
+ template "bin/jobs"
26
10
  chmod "bin/jobs", 0755 & ~File.umask, verbose: false
27
11
  end
28
12
 
29
- def create_migrations
30
- say "Installing database migrations"
31
- arguments = [ "FROM=solid_queue" ]
32
- arguments << "DATABASE=#{options[:database]}" if options[:database].present?
33
- rails_command "railties:install:migrations #{arguments.join(" ")}", inline: true
13
+ def configure_active_job_adapter
14
+ gsub_file Pathname(destination_root).join("config/environments/production.rb"),
15
+ /(# )?config\.active_job\.queue_adapter\s+=.*/,
16
+ "config.active_job.queue_adapter = :solid_queue\n" +
17
+ " config.solid_queue.connects_to = { database: { writing: :queue } }\n"
34
18
  end
35
19
  end
@@ -0,0 +1,18 @@
1
+ default: &default
2
+ dispatchers:
3
+ - polling_interval: 1
4
+ batch_size: 500
5
+ workers:
6
+ - queues: "*"
7
+ threads: 3
8
+ processes: <%%= ENV.fetch("JOB_CONCURRENCY", 1) %>
9
+ polling_interval: 0.1
10
+
11
+ development:
12
+ <<: *default
13
+
14
+ test:
15
+ <<: *default
16
+
17
+ production:
18
+ <<: *default
@@ -0,0 +1,129 @@
1
+ ActiveRecord::Schema[7.1].define(version: 2024_09_04_193154) do
2
+ create_table "solid_queue_blocked_executions", force: :cascade do |t|
3
+ t.integer "job_id", null: false
4
+ t.string "queue_name", null: false
5
+ t.integer "priority", default: 0, null: false
6
+ t.string "concurrency_key", null: false
7
+ t.datetime "expires_at", null: false
8
+ t.datetime "created_at", null: false
9
+ t.index [ "concurrency_key", "priority", "job_id" ], name: "index_solid_queue_blocked_executions_for_release"
10
+ t.index [ "expires_at", "concurrency_key" ], name: "index_solid_queue_blocked_executions_for_maintenance"
11
+ t.index [ "job_id" ], name: "index_solid_queue_blocked_executions_on_job_id", unique: true
12
+ end
13
+
14
+ create_table "solid_queue_claimed_executions", force: :cascade do |t|
15
+ t.integer "job_id", null: false
16
+ t.bigint "process_id"
17
+ t.datetime "created_at", null: false
18
+ t.index [ "job_id" ], name: "index_solid_queue_claimed_executions_on_job_id", unique: true
19
+ t.index [ "process_id", "job_id" ], name: "index_solid_queue_claimed_executions_on_process_id_and_job_id"
20
+ end
21
+
22
+ create_table "solid_queue_failed_executions", force: :cascade do |t|
23
+ t.integer "job_id", null: false
24
+ t.text "error"
25
+ t.datetime "created_at", null: false
26
+ t.index [ "job_id" ], name: "index_solid_queue_failed_executions_on_job_id", unique: true
27
+ end
28
+
29
+ create_table "solid_queue_jobs", force: :cascade do |t|
30
+ t.string "queue_name", null: false
31
+ t.string "class_name", null: false
32
+ t.text "arguments"
33
+ t.integer "priority", default: 0, null: false
34
+ t.string "active_job_id"
35
+ t.datetime "scheduled_at"
36
+ t.datetime "finished_at"
37
+ t.string "concurrency_key"
38
+ t.datetime "created_at", null: false
39
+ t.datetime "updated_at", null: false
40
+ t.index [ "active_job_id" ], name: "index_solid_queue_jobs_on_active_job_id"
41
+ t.index [ "class_name" ], name: "index_solid_queue_jobs_on_class_name"
42
+ t.index [ "finished_at" ], name: "index_solid_queue_jobs_on_finished_at"
43
+ t.index [ "queue_name", "finished_at" ], name: "index_solid_queue_jobs_for_filtering"
44
+ t.index [ "scheduled_at", "finished_at" ], name: "index_solid_queue_jobs_for_alerting"
45
+ end
46
+
47
+ create_table "solid_queue_pauses", force: :cascade do |t|
48
+ t.string "queue_name", null: false
49
+ t.datetime "created_at", null: false
50
+ t.index [ "queue_name" ], name: "index_solid_queue_pauses_on_queue_name", unique: true
51
+ end
52
+
53
+ create_table "solid_queue_processes", force: :cascade do |t|
54
+ t.string "kind", null: false
55
+ t.datetime "last_heartbeat_at", null: false
56
+ t.bigint "supervisor_id"
57
+ t.integer "pid", null: false
58
+ t.string "hostname"
59
+ t.text "metadata"
60
+ t.datetime "created_at", null: false
61
+ t.string "name", null: false
62
+ t.index [ "last_heartbeat_at" ], name: "index_solid_queue_processes_on_last_heartbeat_at"
63
+ t.index [ "name", "supervisor_id" ], name: "index_solid_queue_processes_on_name_and_supervisor_id", unique: true
64
+ t.index [ "supervisor_id" ], name: "index_solid_queue_processes_on_supervisor_id"
65
+ end
66
+
67
+ create_table "solid_queue_ready_executions", force: :cascade do |t|
68
+ t.integer "job_id", null: false
69
+ t.string "queue_name", null: false
70
+ t.integer "priority", default: 0, null: false
71
+ t.datetime "created_at", null: false
72
+ t.index [ "job_id" ], name: "index_solid_queue_ready_executions_on_job_id", unique: true
73
+ t.index [ "priority", "job_id" ], name: "index_solid_queue_poll_all"
74
+ t.index [ "queue_name", "priority", "job_id" ], name: "index_solid_queue_poll_by_queue"
75
+ end
76
+
77
+ create_table "solid_queue_recurring_executions", force: :cascade do |t|
78
+ t.integer "job_id", null: false
79
+ t.string "task_key", null: false
80
+ t.datetime "run_at", null: false
81
+ t.datetime "created_at", null: false
82
+ t.index [ "job_id" ], name: "index_solid_queue_recurring_executions_on_job_id", unique: true
83
+ t.index [ "task_key", "run_at" ], name: "index_solid_queue_recurring_executions_on_task_key_and_run_at", unique: true
84
+ end
85
+
86
+ create_table "solid_queue_recurring_tasks", force: :cascade do |t|
87
+ t.string "key", null: false
88
+ t.string "schedule", null: false
89
+ t.string "command", limit: 2048
90
+ t.string "class_name"
91
+ t.text "arguments"
92
+ t.string "queue_name"
93
+ t.integer "priority", default: 0
94
+ t.boolean "static", default: true, null: false
95
+ t.text "description"
96
+ t.datetime "created_at", null: false
97
+ t.datetime "updated_at", null: false
98
+ t.index [ "key" ], name: "index_solid_queue_recurring_tasks_on_key", unique: true
99
+ t.index [ "static" ], name: "index_solid_queue_recurring_tasks_on_static"
100
+ end
101
+
102
+ create_table "solid_queue_scheduled_executions", force: :cascade do |t|
103
+ t.integer "job_id", null: false
104
+ t.string "queue_name", null: false
105
+ t.integer "priority", default: 0, null: false
106
+ t.datetime "scheduled_at", null: false
107
+ t.datetime "created_at", null: false
108
+ t.index [ "job_id" ], name: "index_solid_queue_scheduled_executions_on_job_id", unique: true
109
+ t.index [ "scheduled_at", "priority", "job_id" ], name: "index_solid_queue_dispatch_all"
110
+ end
111
+
112
+ create_table "solid_queue_semaphores", force: :cascade do |t|
113
+ t.string "key", null: false
114
+ t.integer "value", default: 1, null: false
115
+ t.datetime "expires_at", null: false
116
+ t.datetime "created_at", null: false
117
+ t.datetime "updated_at", null: false
118
+ t.index [ "expires_at" ], name: "index_solid_queue_semaphores_on_expires_at"
119
+ t.index [ "key", "value" ], name: "index_solid_queue_semaphores_on_key_and_value"
120
+ t.index [ "key" ], name: "index_solid_queue_semaphores_on_key", unique: true
121
+ end
122
+
123
+ add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
124
+ add_foreign_key "solid_queue_claimed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
125
+ add_foreign_key "solid_queue_failed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
126
+ add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
127
+ add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
128
+ add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
129
+ end
@@ -1,4 +1,9 @@
1
1
  namespace :solid_queue do
2
+ desc "Install Solid Queue"
3
+ task :install do
4
+ Rails::Command.invoke :generate, [ "solid_queue:install" ]
5
+ end
6
+
2
7
  desc "start solid_queue supervisor to dispatch and process jobs"
3
8
  task start: :environment do
4
9
  SolidQueue::Supervisor.start
@@ -1,3 +1,3 @@
1
1
  module SolidQueue
2
- VERSION = "0.7.1"
2
+ VERSION = "0.8.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rosa Gutierrez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-04 00:00:00.000000000 Z
11
+ date: 2024-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -203,7 +203,6 @@ files:
203
203
  - README.md
204
204
  - Rakefile
205
205
  - UPGRADING.md
206
- - app/jobs/solid_queue/recurring_job.rb
207
206
  - app/models/solid_queue/blocked_execution.rb
208
207
  - app/models/solid_queue/claimed_execution.rb
209
208
  - app/models/solid_queue/execution.rb
@@ -231,19 +230,13 @@ files:
231
230
  - app/models/solid_queue/scheduled_execution.rb
232
231
  - app/models/solid_queue/semaphore.rb
233
232
  - config/routes.rb
234
- - db/migrate/20231211200639_create_solid_queue_tables.rb
235
- - db/migrate/20240110143450_add_missing_index_to_blocked_executions.rb
236
- - db/migrate/20240218110712_create_recurring_executions.rb
237
- - db/migrate/20240719134516_create_recurring_tasks.rb
238
- - db/migrate/20240811173327_add_name_to_processes.rb
239
- - db/migrate/20240813160053_make_name_not_null.rb
240
- - db/migrate/20240819165045_change_solid_queue_recurring_tasks_static_to_not_null.rb
241
233
  - lib/active_job/concurrency_controls.rb
242
234
  - lib/active_job/queue_adapters/solid_queue_adapter.rb
243
235
  - lib/generators/solid_queue/install/USAGE
244
236
  - lib/generators/solid_queue/install/install_generator.rb
245
- - lib/generators/solid_queue/install/templates/config.yml
246
- - lib/generators/solid_queue/install/templates/jobs
237
+ - lib/generators/solid_queue/install/templates/bin/jobs
238
+ - lib/generators/solid_queue/install/templates/config/solid_queue.yml
239
+ - lib/generators/solid_queue/install/templates/db/queue_schema.rb
247
240
  - lib/puma/plugin/solid_queue.rb
248
241
  - lib/solid_queue.rb
249
242
  - lib/solid_queue/app_executor.rb
@@ -283,9 +276,11 @@ metadata:
283
276
  homepage_uri: https://github.com/rails/solid_queue
284
277
  source_code_uri: https://github.com/rails/solid_queue
285
278
  post_install_message: |
286
- Upgrading to Solid Queue 0.4.x, 0.5.x, 0.6.x or 0.7.x? There are some breaking changes about how Solid Queue is started,
287
- configuration and new migrations. Check https://github.com/rails/solid_queue/blob/main/UPGRADING.md
279
+ Upgrading to Solid Queue 0.8.0 from < 0.6.0? You need to upgrade to 0.6.0 first. Check https://github.com/rails/solid_queue/blob/main/UPGRADING.md
288
280
  for upgrade instructions.
281
+
282
+ Upgrading to Solid Queue 0.4.x, 0.5.x, 0.6.x or 0.7.x? There are some breaking changes about how Solid Queue is started,
283
+ configuration and new migrations.
289
284
  rdoc_options: []
290
285
  require_paths:
291
286
  - lib
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class SolidQueue::RecurringJob < ActiveJob::Base
4
- def perform(command)
5
- SolidQueue.instrument(:run_command, command: command) do
6
- eval(command, TOPLEVEL_BINDING, __FILE__, __LINE__)
7
- end
8
- end
9
- end
@@ -1,100 +0,0 @@
1
- class CreateSolidQueueTables < ActiveRecord::Migration[7.0]
2
- def change
3
- create_table :solid_queue_jobs do |t|
4
- t.string :queue_name, null: false
5
- t.string :class_name, null: false, index: true
6
- t.text :arguments
7
- t.integer :priority, default: 0, null: false
8
- t.string :active_job_id, index: true
9
- t.datetime :scheduled_at
10
- t.datetime :finished_at, index: true
11
- t.string :concurrency_key
12
-
13
- t.timestamps
14
-
15
- t.index [ :queue_name, :finished_at ], name: "index_solid_queue_jobs_for_filtering"
16
- t.index [ :scheduled_at, :finished_at ], name: "index_solid_queue_jobs_for_alerting"
17
- end
18
-
19
- create_table :solid_queue_scheduled_executions do |t|
20
- t.references :job, index: { unique: true }, null: false
21
- t.string :queue_name, null: false
22
- t.integer :priority, default: 0, null: false
23
- t.datetime :scheduled_at, null: false
24
-
25
- t.datetime :created_at, null: false
26
-
27
- t.index [ :scheduled_at, :priority, :job_id ], name: "index_solid_queue_dispatch_all"
28
- end
29
-
30
- create_table :solid_queue_ready_executions do |t|
31
- t.references :job, index: { unique: true }, null: false
32
- t.string :queue_name, null: false
33
- t.integer :priority, default: 0, null: false
34
-
35
- t.datetime :created_at, null: false
36
-
37
- t.index [ :priority, :job_id ], name: "index_solid_queue_poll_all"
38
- t.index [ :queue_name, :priority, :job_id ], name: "index_solid_queue_poll_by_queue"
39
- end
40
-
41
- create_table :solid_queue_claimed_executions do |t|
42
- t.references :job, index: { unique: true }, null: false
43
- t.bigint :process_id
44
- t.datetime :created_at, null: false
45
-
46
- t.index [ :process_id, :job_id ]
47
- end
48
-
49
- create_table :solid_queue_blocked_executions do |t|
50
- t.references :job, index: { unique: true }, null: false
51
- t.string :queue_name, null: false
52
- t.integer :priority, default: 0, null: false
53
- t.string :concurrency_key, null: false
54
- t.datetime :expires_at, null: false
55
-
56
- t.datetime :created_at, null: false
57
-
58
- t.index [ :expires_at, :concurrency_key ], name: "index_solid_queue_blocked_executions_for_maintenance"
59
- end
60
-
61
- create_table :solid_queue_failed_executions do |t|
62
- t.references :job, index: { unique: true }, null: false
63
- t.text :error
64
- t.datetime :created_at, null: false
65
- end
66
-
67
- create_table :solid_queue_pauses do |t|
68
- t.string :queue_name, null: false, index: { unique: true }
69
- t.datetime :created_at, null: false
70
- end
71
-
72
- create_table :solid_queue_processes do |t|
73
- t.string :kind, null: false
74
- t.datetime :last_heartbeat_at, null: false, index: true
75
- t.bigint :supervisor_id, index: true
76
-
77
- t.integer :pid, null: false
78
- t.string :hostname
79
- t.text :metadata
80
-
81
- t.datetime :created_at, null: false
82
- end
83
-
84
- create_table :solid_queue_semaphores do |t|
85
- t.string :key, null: false, index: { unique: true }
86
- t.integer :value, default: 1, null: false
87
- t.datetime :expires_at, null: false, index: true
88
-
89
- t.timestamps
90
-
91
- t.index [ :key, :value ], name: "index_solid_queue_semaphores_on_key_and_value"
92
- end
93
-
94
- add_foreign_key :solid_queue_blocked_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade
95
- add_foreign_key :solid_queue_claimed_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade
96
- add_foreign_key :solid_queue_failed_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade
97
- add_foreign_key :solid_queue_ready_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade
98
- add_foreign_key :solid_queue_scheduled_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade
99
- end
100
- end
@@ -1,5 +0,0 @@
1
- class AddMissingIndexToBlockedExecutions < ActiveRecord::Migration[7.1]
2
- def change
3
- add_index :solid_queue_blocked_executions, [ :concurrency_key, :priority, :job_id ], name: "index_solid_queue_blocked_executions_for_release"
4
- end
5
- end
@@ -1,14 +0,0 @@
1
- class CreateRecurringExecutions < ActiveRecord::Migration[7.1]
2
- def change
3
- create_table :solid_queue_recurring_executions do |t|
4
- t.references :job, index: { unique: true }, null: false
5
- t.string :task_key, null: false
6
- t.datetime :run_at, null: false
7
- t.datetime :created_at, null: false
8
-
9
- t.index [ :task_key, :run_at ], unique: true
10
- end
11
-
12
- add_foreign_key :solid_queue_recurring_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade
13
- end
14
- end
@@ -1,20 +0,0 @@
1
- class CreateRecurringTasks < ActiveRecord::Migration[7.1]
2
- def change
3
- create_table :solid_queue_recurring_tasks do |t|
4
- t.string :key, null: false, index: { unique: true }
5
- t.string :schedule, null: false
6
- t.string :command, limit: 2048
7
- t.string :class_name
8
- t.text :arguments
9
-
10
- t.string :queue_name
11
- t.integer :priority, default: 0
12
-
13
- t.boolean :static, default: true, index: true
14
-
15
- t.text :description
16
-
17
- t.timestamps
18
- end
19
- end
20
- end
@@ -1,5 +0,0 @@
1
- class AddNameToProcesses < ActiveRecord::Migration[7.1]
2
- def change
3
- add_column :solid_queue_processes, :name, :string
4
- end
5
- end
@@ -1,16 +0,0 @@
1
- class MakeNameNotNull < ActiveRecord::Migration[7.1]
2
- def up
3
- SolidQueue::Process.where(name: nil).find_each do |process|
4
- process.name ||= [ process.kind.downcase, SecureRandom.hex(10) ].join("-")
5
- process.save!
6
- end
7
-
8
- change_column :solid_queue_processes, :name, :string, null: false
9
- add_index :solid_queue_processes, [ :name, :supervisor_id ], unique: true
10
- end
11
-
12
- def down
13
- remove_index :solid_queue_processes, [ :name, :supervisor_id ]
14
- change_column :solid_queue_processes, :name, :string, null: true
15
- end
16
- end
@@ -1,5 +0,0 @@
1
- class ChangeSolidQueueRecurringTasksStaticToNotNull < ActiveRecord::Migration[7.1]
2
- def change
3
- change_column_null :solid_queue_recurring_tasks, :static, false, true
4
- end
5
- end
@@ -1,18 +0,0 @@
1
- # default: &default
2
- # dispatchers:
3
- # - polling_interval: 1
4
- # batch_size: 500
5
- # workers:
6
- # - queues: "*"
7
- # threads: 3
8
- # processes: 1
9
- # polling_interval: 0.1
10
- #
11
- # development:
12
- # <<: *default
13
- #
14
- # test:
15
- # <<: *default
16
- #
17
- # production:
18
- # <<: *default