Skip to content

Commit fdd7595

Browse files
committed
Set enqueue_after_transaction_commit to true and don't allow changing it
See the discussion in rails/rails#52659. Adapters should set their own behaviour without making users choose. If users want to choose, they can just use Active Job's configuration. Besides, we're changing the value of this to `true` to make it harder for people to run into trouble in the future when switching adapters.
1 parent c5b1756 commit fdd7595

File tree

4 files changed

+27
-4
lines changed

4 files changed

+27
-4
lines changed

README.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ There are several settings that control how Solid Queue works that you can set a
234234
- `preserve_finished_jobs`: whether to keep finished jobs in the `solid_queue_jobs` table—defaults to `true`.
235235
- `clear_finished_jobs_after`: period to keep finished jobs around, in case `preserve_finished_jobs` is true—defaults to 1 day. **Note:** Right now, there's no automatic cleanup of finished jobs. You'd need to do this by periodically invoking `SolidQueue::Job.clear_finished_in_batches`, but this will happen automatically in the near future.
236236
- `default_concurrency_control_period`: the value to be used as the default for the `duration` parameter in [concurrency controls](#concurrency-controls). It defaults to 3 minutes.
237-
- `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).
238237

239238
## Errors when enqueuing
240239

@@ -319,6 +318,29 @@ plugin :solid_queue
319318
```
320319
to your `puma.rb` configuration.
321320

321+
322+
## Jobs and transactional integrity
323+
: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 and viceversa, and ensuring that your job won't be enqueued until the transaction within which you're enqueing it is 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.
324+
325+
Because this can be quite tricky and many people shouldn't need to worry about it, by default Solid Queue is configured in a different database as the main app, **job enqueuing is deferred until any ongoing transaction is committed** thanks to Active Job's built-in capability to do this. This means that even if you run Solid Queue in the same DB as your app, you won't be taking advantage of this transactional integrity.
326+
327+
If you prefer to change this, you can set [`config.active_job.enqueue_after_transaction_commit`](https://edgeguides.rubyonrails.org/configuring.html#config-active-job-enqueue-after-transaction-commit) to `never`. You can also set this on a per-job basis.
328+
329+
If you set that to `never` but still want to make sure you're not inadvertently on transactional integrity, you can make sure that:
330+
- Your jobs relying on specific data 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.
331+
- 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:
332+
333+
```ruby
334+
class ApplicationRecord < ActiveRecord::Base
335+
self.abstract_class = true
336+
337+
connects_to database: { writing: :primary, reading: :replica }
338+
```
339+
340+
```ruby
341+
config.solid_queue.connects_to = { database: { writing: :primary, reading: :replica } }
342+
```
343+
322344
## Recurring tasks
323345

324346
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 the scheduler process and are defined in their own configuration file. By default, the file is located in `config/recurring.yml`, but you can set a different path using the environment variable `SOLID_QUEUE_RECURRING_SCHEDULE` or by using the `--recurring_schedule_file` option with `bin/jobs`, like this:

UPGRADING.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Upgrading to version 1.x
2+
The value returned for `enqueue_after_transaction_commit?` has changed to `true`, and it's no longer configurable. If you want to change this, you need to use Active Job's configuration options.
3+
14
# Upgrading to version 0.9.x
25
This version has two breaking changes regarding configuration:
36
- The default configuration file has changed from `config/solid_queue.yml` to `config/queue.yml`.

lib/active_job/queue_adapters/solid_queue_adapter.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module QueueAdapters
99
# Rails.application.config.active_job.queue_adapter = :solid_queue
1010
class SolidQueueAdapter
1111
def enqueue_after_transaction_commit?
12-
SolidQueue.enqueue_after_transaction_commit
12+
true
1313
end
1414

1515
def enqueue(active_job) # :nodoc:

lib/solid_queue.rb

-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ module SolidQueue
3232

3333
mattr_accessor :shutdown_timeout, default: 5.seconds
3434

35-
mattr_accessor :enqueue_after_transaction_commit, default: false
36-
3735
mattr_accessor :silence_polling, default: true
3836

3937
mattr_accessor :supervisor_pidfile

0 commit comments

Comments
 (0)