Class: SwitchConnection::Proxy
- Inherits:
-
Object
- Object
- SwitchConnection::Proxy
- Defined in:
- lib/switch_connection/proxy.rb
Constant Summary collapse
- AVAILABLE_MODES =
%i[master slave].freeze
- DEFAULT_MODE =
:master
Instance Attribute Summary collapse
-
#initial_name ⇒ Object
readonly
Returns the value of attribute initial_name.
Instance Method Summary collapse
- #cache(&block) ⇒ Object
- #connected? ⇒ Boolean
- #connection ⇒ Object
- #db_specific(db_name) ⇒ Object
- #define_master_model(name) ⇒ Object
- #define_slave_model(name) ⇒ Object
-
#initialize(name) ⇒ Proxy
constructor
A new instance of Proxy.
- #master! ⇒ Object
- #master? ⇒ Boolean
- #mode ⇒ Object
- #model_for_connection ⇒ Object
- #reset_name! ⇒ Object
- #slave! ⇒ Object
- #slave? ⇒ Boolean
- #switch_connection_level ⇒ Object
- #switch_connection_level=(level) ⇒ Object
- #switch_name(new_name, &block) ⇒ Object
- #switch_top_level_connection? ⇒ Boolean
- #thread_local_mode ⇒ Object
- #uncached(&block) ⇒ Object
- #with_master(&block) ⇒ Object
- #with_mode(new_mode, &block) ⇒ Object
- #with_slave(&block) ⇒ Object
Constructor Details
#initialize(name) ⇒ Proxy
Returns a new instance of Proxy.
11 12 13 14 15 16 17 |
# File 'lib/switch_connection/proxy.rb', line 11 def initialize(name) @initial_name = name @current_name = name define_master_model(name) define_slave_model(name) @global_mode = DEFAULT_MODE end |
Instance Attribute Details
#initial_name ⇒ Object (readonly)
Returns the value of attribute initial_name.
6 7 8 |
# File 'lib/switch_connection/proxy.rb', line 6 def initial_name @initial_name end |
Instance Method Details
#cache(&block) ⇒ Object
171 172 173 174 175 |
# File 'lib/switch_connection/proxy.rb', line 171 def cache(&block) r = with_slave { model_for_connection } w = with_master { model_for_connection } r.cache { w.cache(&block) } end |
#connected? ⇒ Boolean
167 168 169 |
# File 'lib/switch_connection/proxy.rb', line 167 def connected? model_for_connection.connected? end |
#connection ⇒ Object
163 164 165 |
# File 'lib/switch_connection/proxy.rb', line 163 def connection model_for_connection.connection end |
#db_specific(db_name) ⇒ Object
47 48 49 50 51 52 |
# File 'lib/switch_connection/proxy.rb', line 47 def db_specific(db_name) base_config = ::ActiveRecord::Base.configurations.fetch(SwitchConnection.config.env) return base_config if db_name == :default db_name.to_s.split('.').inject(base_config) { |h, n| h[n] } end |
#define_master_model(name) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/switch_connection/proxy.rb', line 19 def define_master_model(name) model_name = SwitchConnection.config.master_model_name(name) if model_name model = Class.new(ActiveRecord::Base) Proxy.const_set(model_name, model) master_database_name = SwitchConnection.config.master_database_name(name) model.establish_connection(db_specific(master_database_name)) model else ActiveRecord::Base end end |
#define_slave_model(name) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/switch_connection/proxy.rb', line 32 def define_slave_model(name) return unless SwitchConnection.config.slave_exist?(name) slave_count = SwitchConnection.config.slave_count(name) (0..(slave_count - 1)).map do |index| model_name = SwitchConnection.config.slave_mode_name(name, index) next ActiveRecord::Base unless model_name model = Class.new(ActiveRecord::Base) Proxy.const_set(model_name, model) model.establish_connection(db_specific(SwitchConnection.config.slave_database_name(name, index))) model end end |
#master! ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/switch_connection/proxy.rb', line 91 def master! if thread_local_mode self.thread_local_mode = :master else @global_mode = :master end end |
#master? ⇒ Boolean
99 100 101 |
# File 'lib/switch_connection/proxy.rb', line 99 def master? mode == :master end |
#mode ⇒ Object
63 64 65 |
# File 'lib/switch_connection/proxy.rb', line 63 def mode thread_local_mode || @global_mode end |
#model_for_connection ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/switch_connection/proxy.rb', line 148 def model_for_connection ProxyRepository.checkout(@current_name) # Ensure the target proxy is created model_name = SwitchConnection.config.model_name(@current_name, mode) if model_name Proxy.const_get(model_name) elsif mode == :slave # When only master is specified, re-use master connection. with_master do model_for_connection end else ActiveRecord::Base end end |
#reset_name! ⇒ Object
144 145 146 |
# File 'lib/switch_connection/proxy.rb', line 144 def reset_name! @current_name = @initial_name end |
#slave! ⇒ Object
79 80 81 82 83 84 85 |
# File 'lib/switch_connection/proxy.rb', line 79 def slave! if thread_local_mode self.thread_local_mode = :slave else @global_mode = :slave end end |
#slave? ⇒ Boolean
87 88 89 |
# File 'lib/switch_connection/proxy.rb', line 87 def slave? mode == :slave end |
#switch_connection_level ⇒ Object
71 72 73 |
# File 'lib/switch_connection/proxy.rb', line 71 def switch_connection_level Thread.current[:"switch_point_#{@current_name}_level"] || 0 end |
#switch_connection_level=(level) ⇒ Object
67 68 69 |
# File 'lib/switch_connection/proxy.rb', line 67 def switch_connection_level=(level) Thread.current[:"switch_point_#{@current_name}_level"] = level end |
#switch_name(new_name, &block) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/switch_connection/proxy.rb', line 130 def switch_name(new_name, &block) if block begin old_name = @current_name @current_name = new_name block.call ensure @current_name = old_name end else @current_name = new_name end end |
#switch_top_level_connection? ⇒ Boolean
75 76 77 |
# File 'lib/switch_connection/proxy.rb', line 75 def switch_top_level_connection? switch_connection_level.zero? end |
#thread_local_mode ⇒ Object
54 55 56 |
# File 'lib/switch_connection/proxy.rb', line 54 def thread_local_mode Thread.current[:"switch_point_#{@current_name}_mode"] end |
#uncached(&block) ⇒ Object
177 178 179 180 181 |
# File 'lib/switch_connection/proxy.rb', line 177 def uncached(&block) r = with_slave { model_for_connection } w = with_master { model_for_connection } r.uncached { w.uncached(&block) } end |
#with_master(&block) ⇒ Object
107 108 109 |
# File 'lib/switch_connection/proxy.rb', line 107 def with_master(&block) with_mode(:master, &block) end |
#with_mode(new_mode, &block) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/switch_connection/proxy.rb', line 111 def with_mode(new_mode, &block) unless AVAILABLE_MODES.include?(new_mode) self.switch_connection_level += 1 raise ArgumentError.new("Unknown mode: #{new_mode}") end saved_mode = thread_local_mode if new_mode == :slave && switch_top_level_connection? self.thread_local_mode = :slave elsif new_mode == :master self.thread_local_mode = :master end self.switch_connection_level += 1 block.call ensure self.thread_local_mode = saved_mode self.switch_connection_level -= 1 end |
#with_slave(&block) ⇒ Object
103 104 105 |
# File 'lib/switch_connection/proxy.rb', line 103 def with_slave(&block) with_mode(:slave, &block) end |