Class: ActiveRecord::Middleware::DatabaseSelector::Resolver
Do not use. This class is for internal use only.
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Inherits: | Object |
Defined in: | activerecord/lib/active_record/middleware/database_selector/resolver.rb, activerecord/lib/active_record/middleware/database_selector/resolver/session.rb |
Overview
The Resolver class is used by the ::ActiveRecord::Middleware::DatabaseSelector
middleware to determine which database the request should use.
To change the behavior of the Resolver
class in your application, create a custom resolver class that inherits from Resolver
and implements the methods that need to be changed.
By default the Resolver
class will send read traffic to the replica if it’s been 2 seconds since the last write.
Constant Summary
-
SEND_TO_REPLICA_DELAY =
# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 202.seconds
Class Method Summary
Instance Attribute Summary
- #context readonly
- #delay readonly
- #instrumenter readonly
- #read_from_primary? ⇒ Boolean readonly private
- #time_since_last_write_ok? ⇒ Boolean readonly private
Instance Method Summary
- #read(&blk)
- #reading_request?(request) ⇒ Boolean
- #update_context(response)
- #write(&blk)
- #read_from_primary(&blk) readonly private
- #read_from_replica(&blk) private
- #send_to_replica_delay private
- #write_to_primary private
Constructor Details
.new(context, options = {}) ⇒ Resolver
# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 26
def initialize(context, = {}) @context = context @options = @delay = @options && @options[:delay] ? @options[:delay] : SEND_TO_REPLICA_DELAY @instrumenter = ActiveSupport::Notifications.instrumenter end
Class Method Details
.call(context, options = {})
[ GitHub ]Instance Attribute Details
#context (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 33
attr_reader :context, :delay, :instrumenter
#delay (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 33
attr_reader :context, :delay, :instrumenter
#instrumenter (readonly)
[ GitHub ]
#read_from_primary? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 78
def read_from_primary? !time_since_last_write_ok? end
#time_since_last_write_ok? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 86
def time_since_last_write_ok? Time.now - context. >= send_to_replica_delay end
Instance Method Details
#read(&blk)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 35
def read(&blk) if read_from_primary? read_from_primary(&blk) else read_from_replica(&blk) end end
#read_from_primary(&blk) (readonly, private)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 56
def read_from_primary(&blk) ActiveRecord::Base.connected_to(role: ActiveRecord.writing_role, prevent_writes: true) do instrumenter.instrument("database_selector.active_record.read_from_primary", &blk) end end
#read_from_replica(&blk) (private)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 62
def read_from_replica(&blk) ActiveRecord::Base.connected_to(role: ActiveRecord.reading_role, prevent_writes: true) do instrumenter.instrument("database_selector.active_record.read_from_replica", &blk) end end
#reading_request?(request) ⇒ Boolean
# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 51
def reading_request?(request) request.get? || request.head? end
#send_to_replica_delay (private)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 82
def send_to_replica_delay delay end
#update_context(response)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 47
def update_context(response) context.save(response) end
#write(&blk)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 43
def write(&blk) write_to_primary(&blk) end
#write_to_primary (private)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/database_selector/resolver.rb', line 68
def write_to_primary ActiveRecord::Base.connected_to(role: ActiveRecord.writing_role, prevent_writes: false) do instrumenter.instrument("database_selector.active_record.wrote_to_primary") do yield ensure context. end end end