-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Journaled 5.0: Transactional batching (#25)
This adds transactional batching to journaled. What does that mean? Well, now, by default, when multiple events are emitted inside of a transaction: ```ruby ActiveRecord::Base.transaction do event_1.journal! event_2.journal! end ``` A single job will be enqueued directly before the SQL `COMMIT` statement, batching up the two events. (And if the transaction rolls back, the job will never be enqueued.) This can be disabled with a global config (for testing purposes -- we should eventually remove this config if we find no downsides in the new behavior): ```ruby Journaled.transactional_batching_enabled = !Rails.env.production? ``` What happens if we aren't in a transaction? Well, the same thing that happened before! (A job will be enqueued right away.) (**I'm looking into adding an additional transactional safety check, that would raise an error if `journal!` is called outside of a transaction!** But for I'll save that for a future PR.) Because this bumps the version to 5.0, it also removes compatibility for `Journaled::DeliveryJob` jobs enqueued with legacy (3.1.0-era) arguments. This job now accepts a list of events to emit, rather than a single event-kwarg-blog, so a new legacy input pattern is accepted for compatibility with jobs enqueued by v4.x.x of the gem.
- Loading branch information
Showing
16 changed files
with
523 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
============================ | ||
NOTE FOR UPGRADING JOURNALED | ||
============================ | ||
|
||
If you are upgrading from an older `journaled` version, please be sure to | ||
increment only ONE major version at a time. | ||
|
||
⚠️ IF YOU ARE UPGRADING FROM 3.1 OR EARLIER, you should NOT USE THIS VERSION. ⚠️ | ||
|
||
Instead, install a version of the gem that is backwards compatible with your | ||
app's currently-enqueued journaled jobs: | ||
|
||
gem 'journaled', '~> 4.2.0' # upgrading from 3.0-3.1 | ||
gem 'journaled', '~> 3.1.0' # upgrading from 2.0-2.5 | ||
|
||
For additional upgrade instructions (e.g. how to handle a few BREAKING CHANGES | ||
to environment variables), please see the README: | ||
https://github.com/Betterment/journaled/blob/v5.0.0/README.md#upgrades | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
module Journaled | ||
module Connection | ||
class << self | ||
def available? | ||
Journaled.transactional_batching_enabled && transaction_open? | ||
end | ||
|
||
def stage!(event) | ||
raise TransactionSafetyError, <<~MSG unless transaction_open? | ||
Transaction not available! By default, journaled event batching requires an open database transaction. | ||
MSG | ||
|
||
connection.current_transaction._journaled_staged_events << event | ||
end | ||
|
||
private | ||
|
||
def transaction_open? | ||
connection.transaction_open? | ||
end | ||
|
||
def connection | ||
if Journaled.queue_adapter.in? %w(delayed delayed_job) | ||
Delayed::Job.connection | ||
elsif Journaled.queue_adapter == 'good_job' | ||
GoodJob::BaseRecord.connection | ||
elsif Journaled.queue_adapter == 'que' | ||
Que::ActiveRecord::Model.connection | ||
elsif Journaled.queue_adapter == 'test' && Rails.env.test? | ||
ActiveRecord::Base.connection | ||
else | ||
raise "Unsupported adapter: #{Journaled.queue_adapter}" | ||
end | ||
end | ||
end | ||
|
||
module TestOnlyBehaviors | ||
def transaction_open? | ||
# Transactional fixtures wrap all tests in an outer, non-joinable transaction: | ||
super && (connection.open_transactions > 1 || connection.current_transaction.joinable?) | ||
end | ||
end | ||
|
||
class << self | ||
prepend TestOnlyBehaviors if Rails.env.test? | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module Journaled | ||
class TransactionSafetyError < StandardError; end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require 'active_record/connection_adapters/abstract/transaction' | ||
|
||
module Journaled | ||
module TransactionExt | ||
def initialize(*, **) | ||
super.tap do | ||
raise TransactionSafetyError, <<~MSG unless instance_variable_defined?(:@run_commit_callbacks) | ||
Journaled::TransactionExt expects @run_commit_callbacks to be defined on Transaction! | ||
This is an internal API that may have changed in a recent Rails release. | ||
If you were not expecting to see this error, please file an issue here: | ||
https://github.com/Betterment/journaled/issues | ||
MSG | ||
end | ||
end | ||
|
||
def before_commit_records | ||
super.tap do | ||
Writer.enqueue!(*_journaled_staged_events) if @run_commit_callbacks | ||
end | ||
end | ||
|
||
def commit_records | ||
connection.current_transaction._journaled_staged_events.push(*_journaled_staged_events) unless @run_commit_callbacks | ||
super | ||
end | ||
|
||
def _journaled_staged_events | ||
@_journaled_staged_events ||= [] | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
module Journaled | ||
VERSION = "4.3.0".freeze | ||
VERSION = "5.0.0".freeze | ||
end |
Oops, something went wrong.