Skip to content

Commit

Permalink
Merge pull request #36843 from eileencodes/add-ability-to-unset-preve…
Browse files Browse the repository at this point in the history
…nting-writes

Add ability to unset preventing writes
  • Loading branch information
eileencodes committed Aug 2, 2019
2 parents f3c68c5 + f2de448 commit ac7c938
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1020,8 +1020,8 @@ def initialize
# In some cases you may want to prevent writes to the database
# even if you are on a database that can write. `while_preventing_writes`
# will prevent writes to the database for the duration of the block.
def while_preventing_writes
original, @prevent_writes = @prevent_writes, true
def while_preventing_writes(enabled = true)
original, @prevent_writes = @prevent_writes, enabled
yield
ensure
@prevent_writes = original
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def write(&blk)
private
def read_from_primary(&blk)
ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do
ActiveRecord::Base.connection_handler.while_preventing_writes do
ActiveRecord::Base.connection_handler.while_preventing_writes(true) do
instrumenter.instrument("database_selector.active_record.read_from_primary") do
yield
end
Expand All @@ -64,10 +64,12 @@ def read_from_replica(&blk)

def write_to_primary(&blk)
ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do
instrumenter.instrument("database_selector.active_record.wrote_to_primary") do
yield
ensure
context.update_last_write_timestamp
ActiveRecord::Base.connection_handler.while_preventing_writes(false) do
instrumenter.instrument("database_selector.active_record.wrote_to_primary") do
yield
ensure
context.update_last_write_timestamp
end
end
end
end
Expand Down
34 changes: 34 additions & 0 deletions activerecord/test/cases/database_selector_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,40 @@ def test_read_from_primary_with_options
assert read
end

def test_preventing_writes_turns_off_for_primary_write
resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session, delay: 5.seconds)

# Session should start empty
assert_nil @session_store[:last_write]

called = false
resolver.write do
assert ActiveRecord::Base.connected_to?(role: :writing)
called = true
end
assert called

# and be populated by the last write time
assert @session_store[:last_write]

read = false
write = false
resolver.read do
assert ActiveRecord::Base.connected_to?(role: :writing)
assert ActiveRecord::Base.connection_handler.prevent_writes
read = true

resolver.write do
assert ActiveRecord::Base.connected_to?(role: :writing)
assert_not ActiveRecord::Base.connection_handler.prevent_writes
write = true
end
end

assert write
assert read
end

def test_read_from_replica_with_no_delay
resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session, delay: 0.seconds)

Expand Down

0 comments on commit ac7c938

Please sign in to comment.