Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ gem 'openstax_api'
gem 'apipie-rails'
gem 'maruku'

# Retry failed database transactions
gem 'transaction_retry', github: 'openstax/transaction_retry'

# Lev framework
gem 'lev'

Expand Down
12 changes: 9 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
GIT
remote: https://github.com/openstax/transaction_retry.git
revision: 5a148396c3b332a7e6a1ad5c7e6eb86b68f09829
specs:
transaction_retry (1.0.3)
activerecord (>= 3.0.11)
transaction_isolation (>= 1.0.2)

GEM
remote: https://rubygems.org/
specs:
Expand Down Expand Up @@ -479,9 +487,6 @@ GEM
timecop (0.9.2)
transaction_isolation (1.0.5)
activerecord (>= 3.0.11)
transaction_retry (1.0.3)
activerecord (>= 3.0.11)
transaction_isolation (>= 1.0.2)
turbolinks (5.2.1)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
Expand Down Expand Up @@ -574,6 +579,7 @@ DEPENDENCIES
sortability
thin
timecop
transaction_retry!
turbolinks
uglifier (>= 1.3.0)
web-console
Expand Down
4 changes: 4 additions & 0 deletions config/initializers/transaction_retry.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# TransactionRetry.max_retries = 3
# TransactionRetry.wait_times = [0, 1, 2, 4, 8, 16, 32] # seconds to sleep after retry n
TransactionRetry.retry_on = ActiveRecord::PreparedStatementCacheExpired # or an array of classes is valid too (ActiveRecord::TransactionIsolationConflict is by default always included)
# TransactionRetry.before_retry = ->(retry_num, error) { ... }
20 changes: 20 additions & 0 deletions spec/lib/transaction_retry_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require 'rails_helper'

# Need truncation: true because transaction_retry only retries top-level transactions
RSpec.describe TransactionRetry, type: :lib, truncation: true do
it 'retries ActiveRecord::PreparedStatementCacheExpired' do
result = nil

ActiveRecord::Base.transaction do
if result.nil?
result = 21

raise ActiveRecord::PreparedStatementCacheExpired.new('test')
else
result = 42
end
end

expect(result).to eq 42
end
end
27 changes: 26 additions & 1 deletion spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
config.use_transactional_fixtures = false

# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
Expand All @@ -59,6 +59,31 @@
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!

config.prepend_before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end

config.prepend_before(:all) do
metadata = self.class.metadata
DatabaseCleaner.strategy = metadata[:js] || metadata[:truncation] ? :truncation : :transaction
DatabaseCleaner.start
end

config.prepend_before(:each) do
DatabaseCleaner.start
end

# https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example says:
# "It's also recommended to use append_after to ensure DatabaseCleaner.clean
# runs after the after-test cleanup capybara/rspec installs."
config.append_after(:each) do
DatabaseCleaner.clean
end

config.append_after(:all) do
DatabaseCleaner.clean
end
end

# Adds a convenience method to get interpret the body as JSON and convert to a hash;
Expand Down