diff options
author | Eileen M. Uchitelle <eileencodes@users.noreply.github.com> | 2019-08-02 13:03:03 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-02 13:03:03 -0400 |
commit | ac7c9381f02446bb4e1681ad66cd69d8abe23594 (patch) | |
tree | 4a12db093039c6d9546d37668a53996e80e54e61 /activerecord | |
parent | f3c68c59ed57302ca54f4dfad0e91dbff426962d (diff) | |
parent | f2de448106ca3bb947dc88f96ca7d81d37b5be9a (diff) | |
download | rails-ac7c9381f02446bb4e1681ad66cd69d8abe23594.tar.gz rails-ac7c9381f02446bb4e1681ad66cd69d8abe23594.tar.bz2 rails-ac7c9381f02446bb4e1681ad66cd69d8abe23594.zip |
Merge pull request #36843 from eileencodes/add-ability-to-unset-preventing-writes
Add ability to unset preventing writes
Diffstat (limited to 'activerecord')
3 files changed, 43 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index 36001efdd5..276d5a25d4 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -1020,8 +1020,8 @@ module ActiveRecord # 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 diff --git a/activerecord/lib/active_record/middleware/database_selector/resolver.rb b/activerecord/lib/active_record/middleware/database_selector/resolver.rb index 3eb1039c50..b2aa453a8e 100644 --- a/activerecord/lib/active_record/middleware/database_selector/resolver.rb +++ b/activerecord/lib/active_record/middleware/database_selector/resolver.rb @@ -46,7 +46,7 @@ module ActiveRecord 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 @@ -64,10 +64,12 @@ module ActiveRecord 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 diff --git a/activerecord/test/cases/database_selector_test.rb b/activerecord/test/cases/database_selector_test.rb index fd02d2acb4..340151e6db 100644 --- a/activerecord/test/cases/database_selector_test.rb +++ b/activerecord/test/cases/database_selector_test.rb @@ -123,6 +123,40 @@ module ActiveRecord 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) |