switchman 2.2.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/Rakefile +10 -2
 - data/app/models/switchman/shard.rb +272 -275
 - data/app/models/switchman/unsharded_record.rb +7 -0
 - data/db/migrate/20130328212039_create_switchman_shards.rb +1 -1
 - data/db/migrate/20130328224244_create_default_shard.rb +5 -5
 - data/db/migrate/20161206323434_add_back_default_string_limits_switchman.rb +1 -0
 - data/db/migrate/20180828183945_add_default_shard_index.rb +2 -2
 - data/db/migrate/20180828192111_add_timestamps_to_shards.rb +7 -5
 - data/db/migrate/20190114212900_add_unique_name_indexes.rb +5 -3
 - data/lib/switchman/action_controller/caching.rb +2 -2
 - data/lib/switchman/active_record/abstract_adapter.rb +1 -0
 - data/lib/switchman/active_record/association.rb +78 -89
 - data/lib/switchman/active_record/attribute_methods.rb +58 -73
 - data/lib/switchman/active_record/base.rb +59 -60
 - data/lib/switchman/active_record/calculations.rb +74 -67
 - data/lib/switchman/active_record/connection_pool.rb +14 -43
 - data/lib/switchman/active_record/database_configurations/database_config.rb +13 -0
 - data/lib/switchman/active_record/database_configurations.rb +34 -0
 - data/lib/switchman/active_record/finder_methods.rb +11 -16
 - data/lib/switchman/active_record/log_subscriber.rb +4 -5
 - data/lib/switchman/active_record/migration.rb +7 -51
 - data/lib/switchman/active_record/model_schema.rb +1 -1
 - data/lib/switchman/active_record/persistence.rb +3 -14
 - data/lib/switchman/active_record/postgresql_adapter.rb +125 -169
 - data/lib/switchman/active_record/predicate_builder.rb +2 -2
 - data/lib/switchman/active_record/query_cache.rb +18 -19
 - data/lib/switchman/active_record/query_methods.rb +168 -216
 - data/lib/switchman/active_record/reflection.rb +7 -22
 - data/lib/switchman/active_record/relation.rb +30 -78
 - data/lib/switchman/active_record/spawn_methods.rb +27 -29
 - data/lib/switchman/active_record/statement_cache.rb +18 -35
 - data/lib/switchman/active_record/tasks/database_tasks.rb +16 -0
 - data/lib/switchman/active_support/cache.rb +3 -5
 - data/lib/switchman/arel.rb +13 -8
 - data/lib/switchman/database_server.rb +121 -142
 - data/lib/switchman/default_shard.rb +52 -16
 - data/lib/switchman/engine.rb +62 -59
 - data/lib/switchman/environment.rb +4 -8
 - data/lib/switchman/errors.rb +1 -0
 - data/lib/switchman/guard_rail/relation.rb +5 -7
 - data/lib/switchman/guard_rail.rb +6 -19
 - data/lib/switchman/r_spec_helper.rb +29 -37
 - data/lib/switchman/rails.rb +14 -12
 - data/lib/switchman/schema_cache.rb +1 -9
 - data/lib/switchman/sharded_instrumenter.rb +1 -1
 - data/lib/switchman/standard_error.rb +15 -3
 - data/lib/switchman/test_helper.rb +6 -4
 - data/lib/switchman/version.rb +1 -1
 - data/lib/switchman.rb +3 -5
 - data/lib/tasks/switchman.rake +55 -71
 - metadata +88 -46
 - data/lib/switchman/active_record/batches.rb +0 -11
 - data/lib/switchman/active_record/connection_handler.rb +0 -190
 - data/lib/switchman/active_record/where_clause_factory.rb +0 -36
 - data/lib/switchman/connection_pool_proxy.rb +0 -173
 
    
        data/lib/switchman/engine.rb
    CHANGED
    
    | 
         @@ -4,24 +4,30 @@ module Switchman 
     | 
|
| 
       4 
4 
     | 
    
         
             
              class Engine < ::Rails::Engine
         
     | 
| 
       5 
5 
     | 
    
         
             
                isolate_namespace Switchman
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
                 
     | 
| 
      
 7 
     | 
    
         
            +
                # enable Rails 6.1 style connection handling
         
     | 
| 
      
 8 
     | 
    
         
            +
                config.active_record.legacy_connection_handling = false
         
     | 
| 
      
 9 
     | 
    
         
            +
                config.active_record.writing_role = :primary
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                config.autoload_once_paths << File.expand_path('app/models', config.paths.path)
         
     | 
| 
       8 
12 
     | 
    
         | 
| 
       9 
13 
     | 
    
         
             
                def self.lookup_stores(cache_store_config)
         
     | 
| 
       10 
14 
     | 
    
         
             
                  result = {}
         
     | 
| 
       11 
15 
     | 
    
         
             
                  cache_store_config.each do |key, value|
         
     | 
| 
       12 
16 
     | 
    
         
             
                    next if value.is_a?(String)
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
       13 
18 
     | 
    
         
             
                    result[key] = ::ActiveSupport::Cache.lookup_store(value)
         
     | 
| 
       14 
19 
     | 
    
         
             
                  end
         
     | 
| 
       15 
20 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                  cache_store_config.each do |key, value|
         
     | 
| 
      
 21 
     | 
    
         
            +
                  cache_store_config.each do |key, value| # rubocop:disable Style/CombinableLoops
         
     | 
| 
       17 
22 
     | 
    
         
             
                    next unless value.is_a?(String)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
       18 
24 
     | 
    
         
             
                    result[key] = result[value]
         
     | 
| 
       19 
25 
     | 
    
         
             
                  end
         
     | 
| 
       20 
26 
     | 
    
         
             
                  result
         
     | 
| 
       21 
27 
     | 
    
         
             
                end
         
     | 
| 
       22 
28 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
                initializer 'switchman.initialize_cache', : 
     | 
| 
       24 
     | 
    
         
            -
                  require  
     | 
| 
      
 29 
     | 
    
         
            +
                initializer 'switchman.initialize_cache', before: 'initialize_cache' do
         
     | 
| 
      
 30 
     | 
    
         
            +
                  require 'switchman/active_support/cache'
         
     | 
| 
       25 
31 
     | 
    
         
             
                  ::ActiveSupport::Cache.singleton_class.prepend(ActiveSupport::Cache::ClassMethods)
         
     | 
| 
       26 
32 
     | 
    
         | 
| 
       27 
33 
     | 
    
         
             
                  # if we haven't already setup our cache map out-of-band, set it up from
         
     | 
| 
         @@ -31,9 +37,7 @@ module Switchman 
     | 
|
| 
       31 
37 
     | 
    
         
             
                  # to fill just the Rails.env entry in the cache map.
         
     | 
| 
       32 
38 
     | 
    
         
             
                  unless Switchman.config[:cache_map].present?
         
     | 
| 
       33 
39 
     | 
    
         
             
                    cache_store_config = ::Rails.configuration.cache_store
         
     | 
| 
       34 
     | 
    
         
            -
                    unless cache_store_config.is_a?(Hash)
         
     | 
| 
       35 
     | 
    
         
            -
                      cache_store_config = {::Rails.env => cache_store_config}
         
     | 
| 
       36 
     | 
    
         
            -
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
                    cache_store_config = { ::Rails.env => cache_store_config } unless cache_store_config.is_a?(Hash)
         
     | 
| 
       37 
41 
     | 
    
         | 
| 
       38 
42 
     | 
    
         
             
                    Switchman.config[:cache_map] = Engine.lookup_stores(cache_store_config)
         
     | 
| 
       39 
43 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -42,7 +46,7 @@ module Switchman 
     | 
|
| 
       42 
46 
     | 
    
         
             
                  # config.cache_store) didn't have an entry for Rails.env, add one using
         
     | 
| 
       43 
47 
     | 
    
         
             
                  # lookup_store(nil); matches the behavior of Rails' default
         
     | 
| 
       44 
48 
     | 
    
         
             
                  # initialize_cache initializer when config.cache_store is nil.
         
     | 
| 
       45 
     | 
    
         
            -
                  unless Switchman.config[:cache_map]. 
     | 
| 
      
 49 
     | 
    
         
            +
                  unless Switchman.config[:cache_map].key?(::Rails.env)
         
     | 
| 
       46 
50 
     | 
    
         
             
                    value = ::ActiveSupport::Cache.lookup_store(nil)
         
     | 
| 
       47 
51 
     | 
    
         
             
                    Switchman.config[:cache_map][::Rails.env] = value
         
     | 
| 
       48 
52 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -51,7 +55,7 @@ module Switchman 
     | 
|
| 
       51 
55 
     | 
    
         
             
                    store.middleware if store.respond_to?(:middleware)
         
     | 
| 
       52 
56 
     | 
    
         
             
                  end.compact.uniq
         
     | 
| 
       53 
57 
     | 
    
         
             
                  middlewares.each do |middleware|
         
     | 
| 
       54 
     | 
    
         
            -
                    config.middleware.insert_before( 
     | 
| 
      
 58 
     | 
    
         
            +
                    config.middleware.insert_before('Rack::Runtime', middleware)
         
     | 
| 
       55 
59 
     | 
    
         
             
                  end
         
     | 
| 
       56 
60 
     | 
    
         | 
| 
       57 
61 
     | 
    
         
             
                  # prevent :initialize_cache from trying to (or needing to) set
         
     | 
| 
         @@ -62,40 +66,42 @@ module Switchman 
     | 
|
| 
       62 
66 
     | 
    
         
             
                  ::Rails.cache = Switchman.config[:cache_map][::Rails.env]
         
     | 
| 
       63 
67 
     | 
    
         
             
                end
         
     | 
| 
       64 
68 
     | 
    
         | 
| 
       65 
     | 
    
         
            -
                initializer 'switchman.extend_ar', : 
     | 
| 
      
 69 
     | 
    
         
            +
                initializer 'switchman.extend_ar', before: 'active_record.initialize_database' do
         
     | 
| 
       66 
70 
     | 
    
         
             
                  ::ActiveSupport.on_load(:active_record) do
         
     | 
| 
       67 
     | 
    
         
            -
                    require  
     | 
| 
       68 
     | 
    
         
            -
                    require  
     | 
| 
       69 
     | 
    
         
            -
                    require  
     | 
| 
       70 
     | 
    
         
            -
                    require  
     | 
| 
       71 
     | 
    
         
            -
                    require  
     | 
| 
       72 
     | 
    
         
            -
                    require  
     | 
| 
       73 
     | 
    
         
            -
                    require  
     | 
| 
       74 
     | 
    
         
            -
                    require  
     | 
| 
       75 
     | 
    
         
            -
                    require  
     | 
| 
       76 
     | 
    
         
            -
                    require  
     | 
| 
       77 
     | 
    
         
            -
                    require  
     | 
| 
       78 
     | 
    
         
            -
                    require  
     | 
| 
       79 
     | 
    
         
            -
                    require  
     | 
| 
       80 
     | 
    
         
            -
                    require  
     | 
| 
       81 
     | 
    
         
            -
                    require  
     | 
| 
       82 
     | 
    
         
            -
                    require  
     | 
| 
       83 
     | 
    
         
            -
                    require  
     | 
| 
       84 
     | 
    
         
            -
                    require  
     | 
| 
       85 
     | 
    
         
            -
                    require  
     | 
| 
       86 
     | 
    
         
            -
                    require  
     | 
| 
       87 
     | 
    
         
            -
                    require  
     | 
| 
       88 
     | 
    
         
            -
                    require  
     | 
| 
       89 
     | 
    
         
            -
                    require  
     | 
| 
       90 
     | 
    
         
            -
                    require  
     | 
| 
       91 
     | 
    
         
            -
                    require  
     | 
| 
       92 
     | 
    
         
            -
                    require  
     | 
| 
       93 
     | 
    
         
            -
                     
     | 
| 
       94 
     | 
    
         
            -
                    require "switchman/standard_error"
         
     | 
| 
      
 71 
     | 
    
         
            +
                    require 'switchman/active_record/abstract_adapter'
         
     | 
| 
      
 72 
     | 
    
         
            +
                    require 'switchman/active_record/association'
         
     | 
| 
      
 73 
     | 
    
         
            +
                    require 'switchman/active_record/attribute_methods'
         
     | 
| 
      
 74 
     | 
    
         
            +
                    require 'switchman/active_record/base'
         
     | 
| 
      
 75 
     | 
    
         
            +
                    require 'switchman/active_record/calculations'
         
     | 
| 
      
 76 
     | 
    
         
            +
                    require 'switchman/active_record/connection_pool'
         
     | 
| 
      
 77 
     | 
    
         
            +
                    require 'switchman/active_record/database_configurations'
         
     | 
| 
      
 78 
     | 
    
         
            +
                    require 'switchman/active_record/database_configurations/database_config'
         
     | 
| 
      
 79 
     | 
    
         
            +
                    require 'switchman/active_record/finder_methods'
         
     | 
| 
      
 80 
     | 
    
         
            +
                    require 'switchman/active_record/log_subscriber'
         
     | 
| 
      
 81 
     | 
    
         
            +
                    require 'switchman/active_record/migration'
         
     | 
| 
      
 82 
     | 
    
         
            +
                    require 'switchman/active_record/model_schema'
         
     | 
| 
      
 83 
     | 
    
         
            +
                    require 'switchman/active_record/persistence'
         
     | 
| 
      
 84 
     | 
    
         
            +
                    require 'switchman/active_record/predicate_builder'
         
     | 
| 
      
 85 
     | 
    
         
            +
                    require 'switchman/active_record/query_cache'
         
     | 
| 
      
 86 
     | 
    
         
            +
                    require 'switchman/active_record/query_methods'
         
     | 
| 
      
 87 
     | 
    
         
            +
                    require 'switchman/active_record/reflection'
         
     | 
| 
      
 88 
     | 
    
         
            +
                    require 'switchman/active_record/relation'
         
     | 
| 
      
 89 
     | 
    
         
            +
                    require 'switchman/active_record/spawn_methods'
         
     | 
| 
      
 90 
     | 
    
         
            +
                    require 'switchman/active_record/statement_cache'
         
     | 
| 
      
 91 
     | 
    
         
            +
                    require 'switchman/active_record/tasks/database_tasks'
         
     | 
| 
      
 92 
     | 
    
         
            +
                    require 'switchman/active_record/type_caster'
         
     | 
| 
      
 93 
     | 
    
         
            +
                    require 'switchman/arel'
         
     | 
| 
      
 94 
     | 
    
         
            +
                    require 'switchman/call_super'
         
     | 
| 
      
 95 
     | 
    
         
            +
                    require 'switchman/rails'
         
     | 
| 
      
 96 
     | 
    
         
            +
                    require 'switchman/guard_rail/relation'
         
     | 
| 
      
 97 
     | 
    
         
            +
                    require 'switchman/standard_error'
         
     | 
| 
       95 
98 
     | 
    
         | 
| 
       96 
99 
     | 
    
         
             
                    ::StandardError.include(StandardError)
         
     | 
| 
       97 
100 
     | 
    
         | 
| 
       98 
     | 
    
         
            -
                     
     | 
| 
      
 101 
     | 
    
         
            +
                    self.default_shard = ::Rails.env.to_sym
         
     | 
| 
      
 102 
     | 
    
         
            +
                    self.default_role = :primary
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                    include ActiveRecord::Base
         
     | 
| 
       99 
105 
     | 
    
         
             
                    include ActiveRecord::AttributeMethods
         
     | 
| 
       100 
106 
     | 
    
         
             
                    include ActiveRecord::Persistence
         
     | 
| 
       101 
107 
     | 
    
         
             
                    singleton_class.prepend ActiveRecord::ModelSchema::ClassMethods
         
     | 
| 
         @@ -106,6 +112,8 @@ module Switchman 
     | 
|
| 
       106 
112 
     | 
    
         
             
                    ::ActiveRecord::StatementCache::Substitute.send(:attr_accessor, :primary, :sharded)
         
     | 
| 
       107 
113 
     | 
    
         | 
| 
       108 
114 
     | 
    
         
             
                    ::ActiveRecord::Associations::CollectionAssociation.prepend(ActiveRecord::CollectionAssociation)
         
     | 
| 
      
 115 
     | 
    
         
            +
                    ::ActiveRecord::Associations::HasOneAssociation.prepend(ActiveRecord::ForeignAssociation)
         
     | 
| 
      
 116 
     | 
    
         
            +
                    ::ActiveRecord::Associations::HasManyAssociation.prepend(ActiveRecord::ForeignAssociation)
         
     | 
| 
       109 
117 
     | 
    
         | 
| 
       110 
118 
     | 
    
         
             
                    ::ActiveRecord::PredicateBuilder.singleton_class.prepend(ActiveRecord::PredicateBuilder)
         
     | 
| 
       111 
119 
     | 
    
         | 
| 
         @@ -117,21 +125,22 @@ module Switchman 
     | 
|
| 
       117 
125 
     | 
    
         | 
| 
       118 
126 
     | 
    
         
             
                    ::ActiveRecord::Associations::Preloader::Association.prepend(ActiveRecord::Preloader::Association)
         
     | 
| 
       119 
127 
     | 
    
         
             
                    ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::AbstractAdapter)
         
     | 
| 
       120 
     | 
    
         
            -
                    ::ActiveRecord::ConnectionAdapters::ConnectionHandler.prepend(ActiveRecord::ConnectionHandler)
         
     | 
| 
       121 
128 
     | 
    
         
             
                    ::ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(ActiveRecord::ConnectionPool)
         
     | 
| 
       122 
129 
     | 
    
         
             
                    ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::QueryCache)
         
     | 
| 
       123 
130 
     | 
    
         | 
| 
      
 131 
     | 
    
         
            +
                    ::ActiveRecord::DatabaseConfigurations.prepend(ActiveRecord::DatabaseConfigurations)
         
     | 
| 
      
 132 
     | 
    
         
            +
                    ::ActiveRecord::DatabaseConfigurations::DatabaseConfig.prepend(ActiveRecord::DatabaseConfigurations::DatabaseConfig)
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
       124 
134 
     | 
    
         
             
                    ::ActiveRecord::LogSubscriber.prepend(ActiveRecord::LogSubscriber)
         
     | 
| 
       125 
135 
     | 
    
         
             
                    ::ActiveRecord::Migration.prepend(ActiveRecord::Migration)
         
     | 
| 
       126 
136 
     | 
    
         
             
                    ::ActiveRecord::Migration::Compatibility::V5_0.prepend(ActiveRecord::Migration::Compatibility::V5_0)
         
     | 
| 
       127 
     | 
    
         
            -
                    ::ActiveRecord::MigrationContext.prepend(ActiveRecord::MigrationContext) 
     | 
| 
      
 137 
     | 
    
         
            +
                    ::ActiveRecord::MigrationContext.prepend(ActiveRecord::MigrationContext)
         
     | 
| 
       128 
138 
     | 
    
         
             
                    ::ActiveRecord::Migrator.prepend(ActiveRecord::Migrator)
         
     | 
| 
       129 
139 
     | 
    
         | 
| 
       130 
140 
     | 
    
         
             
                    ::ActiveRecord::Reflection::AbstractReflection.include(ActiveRecord::Reflection::AbstractReflection)
         
     | 
| 
       131 
141 
     | 
    
         
             
                    ::ActiveRecord::Reflection::AssociationReflection.prepend(ActiveRecord::Reflection::AssociationScopeCache)
         
     | 
| 
       132 
142 
     | 
    
         
             
                    ::ActiveRecord::Reflection::ThroughReflection.prepend(ActiveRecord::Reflection::AssociationScopeCache)
         
     | 
| 
       133 
143 
     | 
    
         
             
                    ::ActiveRecord::Reflection::AssociationReflection.prepend(ActiveRecord::Reflection::AssociationReflection)
         
     | 
| 
       134 
     | 
    
         
            -
                    ::ActiveRecord::Relation.prepend(ActiveRecord::Batches)
         
     | 
| 
       135 
144 
     | 
    
         
             
                    ::ActiveRecord::Relation.prepend(ActiveRecord::Calculations)
         
     | 
| 
       136 
145 
     | 
    
         
             
                    ::ActiveRecord::Relation.include(ActiveRecord::FinderMethods)
         
     | 
| 
       137 
146 
     | 
    
         
             
                    ::ActiveRecord::Relation.include(ActiveRecord::QueryMethods)
         
     | 
| 
         @@ -140,9 +149,10 @@ module Switchman 
     | 
|
| 
       140 
149 
     | 
    
         
             
                    ::ActiveRecord::Relation.include(ActiveRecord::SpawnMethods)
         
     | 
| 
       141 
150 
     | 
    
         
             
                    ::ActiveRecord::Relation.include(CallSuper)
         
     | 
| 
       142 
151 
     | 
    
         | 
| 
       143 
     | 
    
         
            -
                    ::ActiveRecord::Relation::WhereClauseFactory.prepend(ActiveRecord::WhereClauseFactory)
         
     | 
| 
       144 
152 
     | 
    
         
             
                    ::ActiveRecord::PredicateBuilder::AssociationQueryValue.prepend(ActiveRecord::PredicateBuilder::AssociationQueryValue)
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                    ::ActiveRecord::Tasks::DatabaseTasks.singleton_class.prepend(ActiveRecord::Tasks::DatabaseTasks)
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
       146 
156 
     | 
    
         
             
                    ::ActiveRecord::TypeCaster::Map.include(ActiveRecord::TypeCaster::Map)
         
     | 
| 
       147 
157 
     | 
    
         
             
                    ::ActiveRecord::TypeCaster::Connection.include(ActiveRecord::TypeCaster::Connection)
         
     | 
| 
       148 
158 
     | 
    
         | 
| 
         @@ -154,12 +164,10 @@ module Switchman 
     | 
|
| 
       154 
164 
     | 
    
         
             
                end
         
     | 
| 
       155 
165 
     | 
    
         | 
| 
       156 
166 
     | 
    
         
             
                def self.foreign_key_check(name, type, limit: nil)
         
     | 
| 
       157 
     | 
    
         
            -
                  if name.to_s =~ /_id\z/ && type.to_s == 'integer' && limit.to_i < 8
         
     | 
| 
       158 
     | 
    
         
            -
                    puts "WARNING: All foreign keys need to be 8-byte integers. #{name} looks like a foreign key. If so, please add the option: `:limit => 8`"
         
     | 
| 
       159 
     | 
    
         
            -
                  end
         
     | 
| 
      
 167 
     | 
    
         
            +
                  puts "WARNING: All foreign keys need to be 8-byte integers. #{name} looks like a foreign key. If so, please add the option: `:limit => 8`" if name.to_s =~ /_id\z/ && type.to_s == 'integer' && limit.to_i < 8
         
     | 
| 
       160 
168 
     | 
    
         
             
                end
         
     | 
| 
       161 
169 
     | 
    
         | 
| 
       162 
     | 
    
         
            -
                initializer 'switchman.extend_connection_adapters', : 
     | 
| 
      
 170 
     | 
    
         
            +
                initializer 'switchman.extend_connection_adapters', after: 'active_record.initialize_database' do
         
     | 
| 
       163 
171 
     | 
    
         
             
                  ::ActiveSupport.on_load(:active_record) do
         
     | 
| 
       164 
172 
     | 
    
         
             
                    ::ActiveRecord::ConnectionAdapters::AbstractAdapter.descendants.each do |klass|
         
     | 
| 
       165 
173 
     | 
    
         
             
                      klass.prepend(ActiveRecord::AbstractAdapter::ForeignKeyCheck)
         
     | 
| 
         @@ -169,15 +177,11 @@ module Switchman 
     | 
|
| 
       169 
177 
     | 
    
         
             
                    ::ActiveRecord::ConnectionAdapters::TableDefinition.prepend(ActiveRecord::TableDefinition)
         
     | 
| 
       170 
178 
     | 
    
         | 
| 
       171 
179 
     | 
    
         
             
                    if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
         
     | 
| 
       172 
     | 
    
         
            -
                      require  
     | 
| 
      
 180 
     | 
    
         
            +
                      require 'switchman/active_record/postgresql_adapter'
         
     | 
| 
       173 
181 
     | 
    
         
             
                      ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecord::PostgreSQLAdapter)
         
     | 
| 
       174 
182 
     | 
    
         
             
                    end
         
     | 
| 
       175 
183 
     | 
    
         | 
| 
       176 
     | 
    
         
            -
                     
     | 
| 
       177 
     | 
    
         
            -
                    # establish a connection here instead
         
     | 
| 
       178 
     | 
    
         
            -
                    if !Shard.instance_variable_get(:@default)
         
     | 
| 
       179 
     | 
    
         
            -
                      ::ActiveRecord::Base.establish_connection
         
     | 
| 
       180 
     | 
    
         
            -
                    end
         
     | 
| 
      
 184 
     | 
    
         
            +
                    Shard.send(:initialize_sharding)
         
     | 
| 
       181 
185 
     | 
    
         
             
                  end
         
     | 
| 
       182 
186 
     | 
    
         
             
                end
         
     | 
| 
       183 
187 
     | 
    
         | 
| 
         @@ -188,21 +192,20 @@ module Switchman 
     | 
|
| 
       188 
192 
     | 
    
         
             
                  end
         
     | 
| 
       189 
193 
     | 
    
         
             
                end
         
     | 
| 
       190 
194 
     | 
    
         | 
| 
       191 
     | 
    
         
            -
                initializer 'switchman.extend_guard_rail', : 
     | 
| 
      
 195 
     | 
    
         
            +
                initializer 'switchman.extend_guard_rail', before: 'switchman.extend_ar' do
         
     | 
| 
       192 
196 
     | 
    
         
             
                  ::ActiveSupport.on_load(:active_record) do
         
     | 
| 
       193 
     | 
    
         
            -
                    require  
     | 
| 
      
 197 
     | 
    
         
            +
                    require 'switchman/guard_rail'
         
     | 
| 
       194 
198 
     | 
    
         | 
| 
       195 
199 
     | 
    
         
             
                    ::GuardRail.singleton_class.prepend(GuardRail::ClassMethods)
         
     | 
| 
       196 
200 
     | 
    
         
             
                  end
         
     | 
| 
       197 
201 
     | 
    
         
             
                end
         
     | 
| 
       198 
202 
     | 
    
         | 
| 
       199 
     | 
    
         
            -
                initializer 'switchman.extend_controller', : 
     | 
| 
      
 203 
     | 
    
         
            +
                initializer 'switchman.extend_controller', after: 'guard_rail.extend_ar' do
         
     | 
| 
       200 
204 
     | 
    
         
             
                  ::ActiveSupport.on_load(:action_controller) do
         
     | 
| 
       201 
     | 
    
         
            -
                    require  
     | 
| 
      
 205 
     | 
    
         
            +
                    require 'switchman/action_controller/caching'
         
     | 
| 
       202 
206 
     | 
    
         | 
| 
       203 
207 
     | 
    
         
             
                    ::ActionController::Base.include(ActionController::Caching)
         
     | 
| 
       204 
208 
     | 
    
         
             
                  end
         
     | 
| 
       205 
209 
     | 
    
         
             
                end
         
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
210 
     | 
    
         
             
              end
         
     | 
| 
       208 
211 
     | 
    
         
             
            end
         
     | 
| 
         @@ -4,17 +4,13 @@ require 'etc' 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            module Switchman
         
     | 
| 
       6 
6 
     | 
    
         
             
              class Environment
         
     | 
| 
      
 7 
     | 
    
         
            +
                def self.cpu_count(nproc_bin = 'nproc')
         
     | 
| 
      
 8 
     | 
    
         
            +
                  return Etc.nprocessors if Etc.respond_to?(:nprocessors)
         
     | 
| 
       7 
9 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                  if Etc.respond_to?(:nprocessors)
         
     | 
| 
       10 
     | 
    
         
            -
                    return Etc.nprocessors
         
     | 
| 
       11 
     | 
    
         
            -
                  end
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                  return `#{nproc_bin}`.to_i
         
     | 
| 
      
 10 
     | 
    
         
            +
                  `#{nproc_bin}`.to_i
         
     | 
| 
       14 
11 
     | 
    
         
             
                rescue Errno::ENOENT
         
     | 
| 
       15 
12 
     | 
    
         
             
                  # an environment where nproc` isnt available
         
     | 
| 
       16 
     | 
    
         
            -
                   
     | 
| 
      
 13 
     | 
    
         
            +
                  0
         
     | 
| 
       17 
14 
     | 
    
         
             
                end
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
15 
     | 
    
         
             
              end
         
     | 
| 
       20 
16 
     | 
    
         
             
            end
         
     | 
    
        data/lib/switchman/errors.rb
    CHANGED
    
    
| 
         @@ -4,19 +4,17 @@ module Switchman 
     | 
|
| 
       4 
4 
     | 
    
         
             
              module GuardRail
         
     | 
| 
       5 
5 
     | 
    
         
             
                module Relation
         
     | 
| 
       6 
6 
     | 
    
         
             
                  def exec_queries(*args)
         
     | 
| 
       7 
     | 
    
         
            -
                    if  
     | 
| 
       8 
     | 
    
         
            -
                      db = Shard.current( 
     | 
| 
       9 
     | 
    
         
            -
                      if ::GuardRail.environment != db.guard_rail_environment
         
     | 
| 
       10 
     | 
    
         
            -
                        return db.unguard { super }
         
     | 
| 
       11 
     | 
    
         
            -
                      end
         
     | 
| 
      
 7 
     | 
    
         
            +
                    if lock_value
         
     | 
| 
      
 8 
     | 
    
         
            +
                      db = Shard.current(connection_classes).database_server
         
     | 
| 
      
 9 
     | 
    
         
            +
                      return db.unguard { super } if ::GuardRail.environment != db.guard_rail_environment
         
     | 
| 
       12 
10 
     | 
    
         
             
                    end
         
     | 
| 
       13 
11 
     | 
    
         
             
                    super
         
     | 
| 
       14 
12 
     | 
    
         
             
                  end
         
     | 
| 
       15 
13 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                  %w 
     | 
| 
      
 14 
     | 
    
         
            +
                  %w[update_all delete_all].each do |method|
         
     | 
| 
       17 
15 
     | 
    
         
             
                    class_eval <<-RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
       18 
16 
     | 
    
         
             
                      def #{method}(*args)
         
     | 
| 
       19 
     | 
    
         
            -
                        db = Shard.current( 
     | 
| 
      
 17 
     | 
    
         
            +
                        db = Shard.current(connection_classes).database_server
         
     | 
| 
       20 
18 
     | 
    
         
             
                        if ::GuardRail.environment != db.guard_rail_environment
         
     | 
| 
       21 
19 
     | 
    
         
             
                          db.unguard { super }
         
     | 
| 
       22 
20 
     | 
    
         
             
                        else
         
     | 
    
        data/lib/switchman/guard_rail.rb
    CHANGED
    
    | 
         @@ -3,27 +3,14 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Switchman
         
     | 
| 
       4 
4 
     | 
    
         
             
              module GuardRail
         
     | 
| 
       5 
5 
     | 
    
         
             
                module ClassMethods
         
     | 
| 
       6 
     | 
    
         
            -
                  def  
     | 
| 
       7 
     | 
    
         
            -
                     
     | 
| 
      
 6 
     | 
    
         
            +
                  def activate(role)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    DatabaseServer.send(:reference_role, role)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    super
         
     | 
| 
       8 
9 
     | 
    
         
             
                  end
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                   
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                    environment ||= :primary
         
     | 
| 
       14 
     | 
    
         
            -
                    activated_environments << environment
         
     | 
| 
       15 
     | 
    
         
            -
                    old_environment = self.environment
         
     | 
| 
       16 
     | 
    
         
            -
                    Thread.current[:guard_rail_environment] = environment
         
     | 
| 
       17 
     | 
    
         
            -
                    old_environment
         
     | 
| 
       18 
     | 
    
         
            -
                  end
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                  # since activate! really is just a variable swap now, it's safe to use in
         
     | 
| 
       21 
     | 
    
         
            -
                  # the ensure block, simplifying the implementation
         
     | 
| 
       22 
     | 
    
         
            -
                  def activate(environment)
         
     | 
| 
       23 
     | 
    
         
            -
                    old_environment = activate!(environment)
         
     | 
| 
       24 
     | 
    
         
            -
                    yield
         
     | 
| 
       25 
     | 
    
         
            -
                  ensure
         
     | 
| 
       26 
     | 
    
         
            -
                    activate!(old_environment)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def activate!(role)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    DatabaseServer.send(:reference_role, role)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    super
         
     | 
| 
       27 
14 
     | 
    
         
             
                  end
         
     | 
| 
       28 
15 
     | 
    
         
             
                end
         
     | 
| 
       29 
16 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1,16 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require  
     | 
| 
      
 3 
     | 
    
         
            +
            require 'switchman/test_helper'
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            module Switchman
         
     | 
| 
       6 
6 
     | 
    
         
             
              # including this module in your specs will give you several shards to
         
     | 
| 
       7 
7 
     | 
    
         
             
              # work with during specs:
         
     | 
| 
       8 
8 
     | 
    
         
             
              #  * Shard.default - the test database itself
         
     | 
| 
       9 
     | 
    
         
            -
              #  * @shard1 - a shard  
     | 
| 
      
 9 
     | 
    
         
            +
              #  * @shard1 - a shard using the same connection as Shard.default
         
     | 
| 
       10 
10 
     | 
    
         
             
              #  * @shard2 - a shard using a dedicated connection
         
     | 
| 
       11 
     | 
    
         
            -
              #  * @shard3 - a shard using the same connection as @shard1 (this might
         
     | 
| 
       12 
     | 
    
         
            -
              #              be Shard.default if they already share a connection, or
         
     | 
| 
       13 
     | 
    
         
            -
              #              a separate shard)
         
     | 
| 
       14 
11 
     | 
    
         
             
              module RSpecHelper
         
     | 
| 
       15 
12 
     | 
    
         
             
                @@keep_the_shards = false
         
     | 
| 
       16 
13 
     | 
    
         
             
                @@shard1 = nil
         
     | 
| 
         @@ -31,14 +28,15 @@ module Switchman 
     | 
|
| 
       31 
28 
     | 
    
         
             
                  root_group.prepend_before(:all) do |group|
         
     | 
| 
       32 
29 
     | 
    
         
             
                    next if @@shard1
         
     | 
| 
       33 
30 
     | 
    
         
             
                    next if @@sharding_failed
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
       34 
32 
     | 
    
         
             
                    # if we aren't actually going to run a sharding group/example,
         
     | 
| 
       35 
33 
     | 
    
         
             
                    # don't set it up after all
         
     | 
| 
       36 
34 
     | 
    
         
             
                    groups = group.class.descendant_filtered_examples.map(&:example_group).uniq
         
     | 
| 
       37 
     | 
    
         
            -
                    next unless groups.any?{ | 
     | 
| 
      
 35 
     | 
    
         
            +
                    next unless groups.any? { |descendant_group| RSpecHelper.included_in?(descendant_group) }
         
     | 
| 
       38 
36 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                    puts  
     | 
| 
      
 37 
     | 
    
         
            +
                    puts 'Setting up sharding for all specs...'
         
     | 
| 
       40 
38 
     | 
    
         
             
                    Shard.delete_all
         
     | 
| 
       41 
     | 
    
         
            -
                    Switchman.cache.delete( 
     | 
| 
      
 39 
     | 
    
         
            +
                    Switchman.cache.delete('default_shard')
         
     | 
| 
       42 
40 
     | 
    
         | 
| 
       43 
41 
     | 
    
         
             
                    @@shard1, @@shard2 = TestHelper.recreate_persistent_test_shards
         
     | 
| 
       44 
42 
     | 
    
         
             
                    @@default_shard = Shard.default
         
     | 
| 
         @@ -49,23 +47,17 @@ module Switchman 
     | 
|
| 
       49 
47 
     | 
    
         
             
                      begin
         
     | 
| 
       50 
48 
     | 
    
         
             
                        @@shard1 = @@shard1.create_new_shard
         
     | 
| 
       51 
49 
     | 
    
         
             
                        @@shard2 = @@shard2.create_new_shard
         
     | 
| 
       52 
     | 
    
         
            -
                        if @@shard1.database_server == Shard.default.database_server
         
     | 
| 
       53 
     | 
    
         
            -
                          @@shard3 = nil
         
     | 
| 
       54 
     | 
    
         
            -
                        else
         
     | 
| 
       55 
     | 
    
         
            -
                          @@shard3 = @@shard1.database_server.create_new_shard
         
     | 
| 
       56 
     | 
    
         
            -
                        end
         
     | 
| 
       57 
50 
     | 
    
         
             
                      rescue => e
         
     | 
| 
       58 
     | 
    
         
            -
                         
     | 
| 
      
 51 
     | 
    
         
            +
                        warn 'Sharding setup FAILED!:'
         
     | 
| 
       59 
52 
     | 
    
         
             
                        while e
         
     | 
| 
       60 
     | 
    
         
            -
                           
     | 
| 
       61 
     | 
    
         
            -
                           
     | 
| 
      
 53 
     | 
    
         
            +
                          warn "\n#{e}\n"
         
     | 
| 
      
 54 
     | 
    
         
            +
                          warn e.backtrace
         
     | 
| 
       62 
55 
     | 
    
         
             
                          e = e.respond_to?(:cause) ? e.cause : nil
         
     | 
| 
       63 
56 
     | 
    
         
             
                        end
         
     | 
| 
       64 
57 
     | 
    
         
             
                        @@sharding_failed = true
         
     | 
| 
       65 
     | 
    
         
            -
                         
     | 
| 
       66 
     | 
    
         
            -
                         
     | 
| 
       67 
     | 
    
         
            -
                         
     | 
| 
       68 
     | 
    
         
            -
                        @@shard1 = @@shard2 = @@shard3 = nil
         
     | 
| 
      
 58 
     | 
    
         
            +
                        @@shard1&.drop_database rescue nil
         
     | 
| 
      
 59 
     | 
    
         
            +
                        @@shard2&.drop_database rescue nil
         
     | 
| 
      
 60 
     | 
    
         
            +
                        @@shard1 = @@shard2 = nil
         
     | 
| 
       69 
61 
     | 
    
         
             
                        Shard.delete_all
         
     | 
| 
       70 
62 
     | 
    
         
             
                        Shard.default(reload: true)
         
     | 
| 
       71 
63 
     | 
    
         
             
                        next
         
     | 
| 
         @@ -74,24 +66,20 @@ module Switchman 
     | 
|
| 
       74 
66 
     | 
    
         
             
                    # we'll re-persist in the group's `before :all`; we don't want them to exist
         
     | 
| 
       75 
67 
     | 
    
         
             
                    # in the db before then
         
     | 
| 
       76 
68 
     | 
    
         
             
                    Shard.delete_all
         
     | 
| 
       77 
     | 
    
         
            -
                    Switchman.cache.delete( 
     | 
| 
      
 69 
     | 
    
         
            +
                    Switchman.cache.delete('default_shard')
         
     | 
| 
       78 
70 
     | 
    
         
             
                    Shard.default(reload: true)
         
     | 
| 
       79 
     | 
    
         
            -
                    puts  
     | 
| 
      
 71 
     | 
    
         
            +
                    puts 'Done!'
         
     | 
| 
       80 
72 
     | 
    
         | 
| 
       81 
73 
     | 
    
         
             
                    at_exit do
         
     | 
| 
       82 
74 
     | 
    
         
             
                      # preserve rspec's exit status
         
     | 
| 
       83 
     | 
    
         
            -
                      status= $!.is_a?(::SystemExit) ? $!.status : nil
         
     | 
| 
       84 
     | 
    
         
            -
                      puts  
     | 
| 
      
 75 
     | 
    
         
            +
                      status = $!.is_a?(::SystemExit) ? $!.status : nil
         
     | 
| 
      
 76 
     | 
    
         
            +
                      puts 'Tearing down sharding for all specs'
         
     | 
| 
       85 
77 
     | 
    
         
             
                      @@shard1.database_server.destroy unless @@shard1.database_server == Shard.default.database_server
         
     | 
| 
       86 
78 
     | 
    
         
             
                      unless @@keep_the_shards
         
     | 
| 
       87 
79 
     | 
    
         
             
                        @@shard1.drop_database
         
     | 
| 
       88 
80 
     | 
    
         
             
                        @@shard1.destroy
         
     | 
| 
       89 
81 
     | 
    
         
             
                        @@shard2.drop_database
         
     | 
| 
       90 
82 
     | 
    
         
             
                        @@shard2.destroy
         
     | 
| 
       91 
     | 
    
         
            -
                        if @@shard3
         
     | 
| 
       92 
     | 
    
         
            -
                          @@shard3.drop_database
         
     | 
| 
       93 
     | 
    
         
            -
                          @@shard3.destroy
         
     | 
| 
       94 
     | 
    
         
            -
                        end
         
     | 
| 
       95 
83 
     | 
    
         
             
                      end
         
     | 
| 
       96 
84 
     | 
    
         
             
                      @@shard2.database_server.destroy
         
     | 
| 
       97 
85 
     | 
    
         
             
                      exit status if status
         
     | 
| 
         @@ -100,10 +88,11 @@ module Switchman 
     | 
|
| 
       100 
88 
     | 
    
         | 
| 
       101 
89 
     | 
    
         
             
                  klass.before(:all) do
         
     | 
| 
       102 
90 
     | 
    
         
             
                    next if @@sharding_failed
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
       103 
92 
     | 
    
         
             
                    dup = @@default_shard.dup
         
     | 
| 
       104 
93 
     | 
    
         
             
                    dup.id = @@default_shard.id
         
     | 
| 
       105 
94 
     | 
    
         
             
                    dup.save!
         
     | 
| 
       106 
     | 
    
         
            -
                    Switchman.cache.delete( 
     | 
| 
      
 95 
     | 
    
         
            +
                    Switchman.cache.delete('default_shard')
         
     | 
| 
       107 
96 
     | 
    
         
             
                    Shard.default(reload: true)
         
     | 
| 
       108 
97 
     | 
    
         
             
                    dup = @@shard1.dup
         
     | 
| 
       109 
98 
     | 
    
         
             
                    dup.id = @@shard1.id
         
     | 
| 
         @@ -111,17 +100,12 @@ module Switchman 
     | 
|
| 
       111 
100 
     | 
    
         
             
                    dup = @@shard2.dup
         
     | 
| 
       112 
101 
     | 
    
         
             
                    dup.id = @@shard2.id
         
     | 
| 
       113 
102 
     | 
    
         
             
                    dup.save!
         
     | 
| 
       114 
     | 
    
         
            -
                    if @@shard3
         
     | 
| 
       115 
     | 
    
         
            -
                      dup = @@shard3.dup
         
     | 
| 
       116 
     | 
    
         
            -
                      dup.id = @@shard3.id
         
     | 
| 
       117 
     | 
    
         
            -
                      dup.save!
         
     | 
| 
       118 
     | 
    
         
            -
                    end
         
     | 
| 
       119 
103 
     | 
    
         
             
                    @shard1, @shard2 = @@shard1, @@shard2
         
     | 
| 
       120 
     | 
    
         
            -
                    @shard3 = @@shard3 ? @@shard3 : Shard.default
         
     | 
| 
       121 
104 
     | 
    
         
             
                  end
         
     | 
| 
       122 
105 
     | 
    
         | 
| 
       123 
106 
     | 
    
         
             
                  klass.before do
         
     | 
| 
       124 
     | 
    
         
            -
                    raise  
     | 
| 
      
 107 
     | 
    
         
            +
                    raise 'Sharding did not set up correctly' if @@sharding_failed
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
       125 
109 
     | 
    
         
             
                    Shard.clear_cache
         
     | 
| 
       126 
110 
     | 
    
         
             
                    if use_transactional_tests
         
     | 
| 
       127 
111 
     | 
    
         
             
                      Shard.default(reload: true)
         
     | 
| 
         @@ -139,6 +123,7 @@ module Switchman 
     | 
|
| 
       139 
123 
     | 
    
         | 
| 
       140 
124 
     | 
    
         
             
                  klass.after do
         
     | 
| 
       141 
125 
     | 
    
         
             
                    next if @@sharding_failed
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
       142 
127 
     | 
    
         
             
                    if use_transactional_tests
         
     | 
| 
       143 
128 
     | 
    
         
             
                      shards = [@shard2]
         
     | 
| 
       144 
129 
     | 
    
         
             
                      shards << @shard1 unless @shard1.database_server == Shard.default.database_server
         
     | 
| 
         @@ -148,11 +133,18 @@ module Switchman 
     | 
|
| 
       148 
133 
     | 
    
         
             
                        end
         
     | 
| 
       149 
134 
     | 
    
         
             
                      end
         
     | 
| 
       150 
135 
     | 
    
         
             
                    end
         
     | 
| 
      
 136 
     | 
    
         
            +
                    # clean up after specs
         
     | 
| 
      
 137 
     | 
    
         
            +
                    DatabaseServer.all.each do |ds|
         
     | 
| 
      
 138 
     | 
    
         
            +
                      if ds.fake? && ds != @shard2.database_server
         
     | 
| 
      
 139 
     | 
    
         
            +
                        ds.shards.delete_all unless use_transactional_tests
         
     | 
| 
      
 140 
     | 
    
         
            +
                        ds.destroy
         
     | 
| 
      
 141 
     | 
    
         
            +
                      end
         
     | 
| 
      
 142 
     | 
    
         
            +
                    end
         
     | 
| 
       151 
143 
     | 
    
         
             
                  end
         
     | 
| 
       152 
144 
     | 
    
         | 
| 
       153 
145 
     | 
    
         
             
                  klass.after(:all) do
         
     | 
| 
       154 
146 
     | 
    
         
             
                    Shard.connection.update("TRUNCATE #{Shard.quoted_table_name} CASCADE")
         
     | 
| 
       155 
     | 
    
         
            -
                    Switchman.cache.delete( 
     | 
| 
      
 147 
     | 
    
         
            +
                    Switchman.cache.delete('default_shard')
         
     | 
| 
       156 
148 
     | 
    
         
             
                    Shard.default(reload: true)
         
     | 
| 
       157 
149 
     | 
    
         
             
                  end
         
     | 
| 
       158 
150 
     | 
    
         
             
                end
         
     | 
    
        data/lib/switchman/rails.rb
    CHANGED
    
    | 
         @@ -1,18 +1,20 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            module Switchman 
     | 
| 
       4 
     | 
    
         
            -
              module  
     | 
| 
       5 
     | 
    
         
            -
                 
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Switchman
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Rails
         
     | 
| 
      
 5 
     | 
    
         
            +
                module ClassMethods
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.prepended(klass)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    # in Rails 4+, the Rails.cache= method was used during bootstrap to set
         
     | 
| 
      
 8 
     | 
    
         
            +
                    # Rails.cache(_without_sharding) to the value from the config file. but now
         
     | 
| 
      
 9 
     | 
    
         
            +
                    # that that's done (the bootstrap happened before this module is included
         
     | 
| 
      
 10 
     | 
    
         
            +
                    # into Rails), we want to make sure no one tries to assign to Rails.cache,
         
     | 
| 
      
 11 
     | 
    
         
            +
                    # because it would be wrong w.r.t. sharding.
         
     | 
| 
      
 12 
     | 
    
         
            +
                    klass.send(:remove_method, :cache=)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def cache
         
     | 
| 
      
 16 
     | 
    
         
            +
                    Switchman::Shard.current.database_server.cache_store
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
       16 
18 
     | 
    
         
             
                end
         
     | 
| 
       17 
19 
     | 
    
         
             
              end
         
     | 
| 
       18 
20 
     | 
    
         
             
            end
         
     | 
| 
         @@ -5,22 +5,14 @@ module Switchman 
     | 
|
| 
       5 
5 
     | 
    
         
             
                delegate :connection, to: :pool
         
     | 
| 
       6 
6 
     | 
    
         
             
                attr_reader :pool
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                SHARED_IVS = %i{@columns @columns_hash @primary_keys @data_sources @indexes}.freeze
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
8 
     | 
    
         
             
                def initialize(pool)
         
     | 
| 
       11 
9 
     | 
    
         
             
                  @pool = pool
         
     | 
| 
       12 
10 
     | 
    
         
             
                  super(nil)
         
     | 
| 
       13 
11 
     | 
    
         
             
                end
         
     | 
| 
       14 
12 
     | 
    
         | 
| 
       15 
13 
     | 
    
         
             
                def copy_values(other_cache)
         
     | 
| 
       16 
     | 
    
         
            -
                  SHARED_IVS.each do |iv|
         
     | 
| 
       17 
     | 
    
         
            -
                    instance_variable_get(iv).replace(other_cache.instance_variable_get(iv))
         
     | 
| 
       18 
     | 
    
         
            -
                  end
         
     | 
| 
       19 
     | 
    
         
            -
                end
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                def copy_references(other_cache)
         
     | 
| 
       22 
14 
     | 
    
         
             
                  # use the same cached values but still fall back to the correct pool
         
     | 
| 
       23 
     | 
    
         
            -
                   
     | 
| 
      
 15 
     | 
    
         
            +
                  %i[@columns @columns_hash @primary_keys @data_sources].each do |iv|
         
     | 
| 
       24 
16 
     | 
    
         
             
                    instance_variable_set(iv, other_cache.instance_variable_get(iv))
         
     | 
| 
       25 
17 
     | 
    
         
             
                  end
         
     | 
| 
       26 
18 
     | 
    
         
             
                end
         
     | 
| 
         @@ -7,7 +7,7 @@ module Switchman 
     | 
|
| 
       7 
7 
     | 
    
         
             
                  @shard_host = shard_host
         
     | 
| 
       8 
8 
     | 
    
         
             
                end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                def instrument(name, payload={})
         
     | 
| 
      
 10 
     | 
    
         
            +
                def instrument(name, payload = {})
         
     | 
| 
       11 
11 
     | 
    
         
             
                  shard = @shard_host&.shard
         
     | 
| 
       12 
12 
     | 
    
         
             
                  # attribute_methods_generated? will be false during a reload -
         
     | 
| 
       13 
13 
     | 
    
         
             
                  # when we might be doing a query while defining attribute methods,
         
     | 
| 
         @@ -3,12 +3,24 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Switchman
         
     | 
| 
       4 
4 
     | 
    
         
             
              module StandardError
         
     | 
| 
       5 
5 
     | 
    
         
             
                def initialize(*args)
         
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
      
 6 
     | 
    
         
            +
                  # Shard.current can throw this when switchman isn't working right; if we try to
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # do our stuff here, it'll cause a SystemStackError, which is a pain to deal with
         
     | 
| 
      
 8 
     | 
    
         
            +
                  if is_a?(::ActiveRecord::ConnectionNotEstablished)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    super
         
     | 
| 
      
 10 
     | 
    
         
            +
                    return
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  if defined?(Shard)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @active_shards = Shard.sharded_models.map do |klass|
         
     | 
| 
      
 15 
     | 
    
         
            +
                      [klass, Shard.current(klass)]
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end.compact.to_h
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       7 
19 
     | 
    
         
             
                  super
         
     | 
| 
       8 
20 
     | 
    
         
             
                end
         
     | 
| 
       9 
21 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                def current_shard( 
     | 
| 
       11 
     | 
    
         
            -
                  @active_shards&.[]( 
     | 
| 
      
 22 
     | 
    
         
            +
                def current_shard(klass = ::ActiveRecord::Base)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  @active_shards&.[](klass) || Shard.default
         
     | 
| 
       12 
24 
     | 
    
         
             
                end
         
     | 
| 
       13 
25 
     | 
    
         
             
              end
         
     | 
| 
       14 
26 
     | 
    
         
             
            end
         
     | 
| 
         @@ -11,6 +11,7 @@ module Switchman 
     | 
|
| 
       11 
11 
     | 
    
         
             
                        Shard.create!(default: true)
         
     | 
| 
       12 
12 
     | 
    
         
             
                      rescue
         
     | 
| 
       13 
13 
     | 
    
         
             
                        raise unless dont_create
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       14 
15 
     | 
    
         
             
                        # database doesn't exist yet, presumably cause we're creating it right now
         
     | 
| 
       15 
16 
     | 
    
         
             
                        return [nil, nil]
         
     | 
| 
       16 
17 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -18,7 +19,7 @@ module Switchman 
     | 
|
| 
       18 
19 
     | 
    
         
             
                    end
         
     | 
| 
       19 
20 
     | 
    
         | 
| 
       20 
21 
     | 
    
         
             
                    server1 = Shard.default.database_server
         
     | 
| 
       21 
     | 
    
         
            -
                    server2 = DatabaseServer.create(Shard.default.database_server.config 
     | 
| 
      
 22 
     | 
    
         
            +
                    server2 = DatabaseServer.create(Shard.default.database_server.config)
         
     | 
| 
       22 
23 
     | 
    
         | 
| 
       23 
24 
     | 
    
         
             
                    if server1 == Shard.default.database_server && server1.config[:shard1] && server1.config[:shard2]
         
     | 
| 
       24 
25 
     | 
    
         
             
                      # look for the shards in the db already
         
     | 
| 
         @@ -49,8 +50,8 @@ module Switchman 
     | 
|
| 
       49 
50 
     | 
    
         
             
                        shard1.destroy
         
     | 
| 
       50 
51 
     | 
    
         
             
                        shard2.drop_database rescue nil
         
     | 
| 
       51 
52 
     | 
    
         
             
                        shard2.destroy
         
     | 
| 
       52 
     | 
    
         
            -
                        shard1 = server1.create_new_shard(: 
     | 
| 
       53 
     | 
    
         
            -
                        shard2 = server2.create_new_shard(: 
     | 
| 
      
 53 
     | 
    
         
            +
                        shard1 = server1.create_new_shard(name: server1.config[:shard1])
         
     | 
| 
      
 54 
     | 
    
         
            +
                        shard2 = server2.create_new_shard(name: server1.config[:shard2])
         
     | 
| 
       54 
55 
     | 
    
         
             
                      end
         
     | 
| 
       55 
56 
     | 
    
         
             
                      [shard1, shard2]
         
     | 
| 
       56 
57 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -59,11 +60,12 @@ module Switchman 
     | 
|
| 
       59 
60 
     | 
    
         
             
                  end
         
     | 
| 
       60 
61 
     | 
    
         | 
| 
       61 
62 
     | 
    
         
             
                  private
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
       62 
64 
     | 
    
         
             
                  def find_existing_test_shard(server, name)
         
     | 
| 
       63 
65 
     | 
    
         
             
                    if server == Shard.default.database_server
         
     | 
| 
       64 
66 
     | 
    
         
             
                      server.shards.where(name: name).first
         
     | 
| 
       65 
67 
     | 
    
         
             
                    else
         
     | 
| 
       66 
     | 
    
         
            -
                      shard = Shard.where( 
     | 
| 
      
 68 
     | 
    
         
            +
                      shard = Shard.where('database_server_id IS NOT NULL AND name=?', name).first
         
     | 
| 
       67 
69 
     | 
    
         
             
                      # if somehow databases got created in a different order, change the shard to match
         
     | 
| 
       68 
70 
     | 
    
         
             
                      shard.database_server = server if shard
         
     | 
| 
       69 
71 
     | 
    
         
             
                      shard
         
     | 
    
        data/lib/switchman/version.rb
    CHANGED
    
    
    
        data/lib/switchman.rb
    CHANGED
    
    | 
         @@ -1,8 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require  
     | 
| 
       4 
     | 
    
         
            -
            require  
     | 
| 
       5 
     | 
    
         
            -
            require  
     | 
| 
      
 3 
     | 
    
         
            +
            require 'guard_rail'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'switchman/open4'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'switchman/engine'
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            module Switchman
         
     | 
| 
       8 
8 
     | 
    
         
             
              def self.config
         
     | 
| 
         @@ -17,6 +17,4 @@ module Switchman 
     | 
|
| 
       17 
17 
     | 
    
         
             
              def self.cache=(cache)
         
     | 
| 
       18 
18 
     | 
    
         
             
                @cache = cache
         
     | 
| 
       19 
19 
     | 
    
         
             
              end
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
              class OrderOnMultiShardQuery < RuntimeError; end
         
     | 
| 
       22 
20 
     | 
    
         
             
            end
         
     |