switchman 3.0.14 → 3.5.20

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +16 -15
  3. data/db/migrate/20180828183945_add_default_shard_index.rb +1 -1
  4. data/db/migrate/20190114212900_add_unique_name_indexes.rb +10 -4
  5. data/lib/switchman/action_controller/caching.rb +2 -2
  6. data/lib/switchman/active_record/abstract_adapter.rb +6 -6
  7. data/lib/switchman/active_record/associations.rb +365 -0
  8. data/lib/switchman/active_record/attribute_methods.rb +188 -99
  9. data/lib/switchman/active_record/base.rb +185 -40
  10. data/lib/switchman/active_record/calculations.rb +64 -40
  11. data/lib/switchman/active_record/connection_handler.rb +18 -0
  12. data/lib/switchman/active_record/connection_pool.rb +24 -5
  13. data/lib/switchman/active_record/database_configurations.rb +37 -13
  14. data/lib/switchman/active_record/finder_methods.rb +46 -16
  15. data/lib/switchman/active_record/log_subscriber.rb +11 -5
  16. data/lib/switchman/active_record/migration.rb +52 -8
  17. data/lib/switchman/active_record/model_schema.rb +1 -1
  18. data/lib/switchman/active_record/persistence.rb +31 -3
  19. data/lib/switchman/active_record/postgresql_adapter.rb +11 -10
  20. data/lib/switchman/active_record/predicate_builder.rb +2 -2
  21. data/lib/switchman/active_record/query_cache.rb +49 -20
  22. data/lib/switchman/active_record/query_methods.rb +187 -136
  23. data/lib/switchman/active_record/reflection.rb +1 -1
  24. data/lib/switchman/active_record/relation.rb +33 -26
  25. data/lib/switchman/active_record/spawn_methods.rb +2 -2
  26. data/lib/switchman/active_record/statement_cache.rb +11 -7
  27. data/lib/switchman/active_record/table_definition.rb +1 -1
  28. data/lib/switchman/active_record/tasks/database_tasks.rb +6 -1
  29. data/lib/switchman/active_record/test_fixtures.rb +26 -16
  30. data/lib/switchman/active_support/cache.rb +20 -1
  31. data/lib/switchman/arel.rb +34 -18
  32. data/lib/switchman/call_super.rb +8 -2
  33. data/lib/switchman/database_server.rb +91 -45
  34. data/lib/switchman/default_shard.rb +14 -5
  35. data/lib/switchman/engine.rb +79 -126
  36. data/lib/switchman/environment.rb +2 -2
  37. data/lib/switchman/errors.rb +17 -2
  38. data/lib/switchman/guard_rail/relation.rb +8 -10
  39. data/lib/switchman/guard_rail.rb +5 -0
  40. data/lib/switchman/parallel.rb +68 -0
  41. data/lib/switchman/r_spec_helper.rb +14 -11
  42. data/lib/switchman/rails.rb +2 -5
  43. data/{app/models → lib}/switchman/shard.rb +186 -189
  44. data/lib/switchman/sharded_instrumenter.rb +5 -1
  45. data/lib/switchman/shared_schema_cache.rb +11 -0
  46. data/lib/switchman/standard_error.rb +6 -5
  47. data/lib/switchman/test_helper.rb +2 -2
  48. data/{app/models → lib}/switchman/unsharded_record.rb +1 -1
  49. data/lib/switchman/version.rb +1 -1
  50. data/lib/switchman.rb +44 -12
  51. data/lib/tasks/switchman.rake +74 -53
  52. metadata +42 -53
  53. data/lib/switchman/active_record/association.rb +0 -206
  54. data/lib/switchman/open4.rb +0 -80
data/lib/switchman.rb CHANGED
@@ -1,22 +1,54 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'guard_rail'
4
- require 'switchman/open4'
5
- require 'switchman/engine'
3
+ require "guard_rail"
4
+ require "zeitwerk"
6
5
 
7
- module Switchman
8
- def self.config
9
- # TODO: load from yaml
10
- @config ||= {}
6
+ class SwitchmanInflector < Zeitwerk::GemInflector
7
+ def camelize(basename, abspath)
8
+ if basename =~ /\Apostgresql_(.*)/
9
+ "PostgreSQL" + super($1, abspath)
10
+ else
11
+ super
12
+ end
11
13
  end
14
+ end
12
15
 
13
- def self.cache
14
- (@cache.respond_to?(:call) ? @cache.call : @cache) || ::Rails.cache
15
- end
16
+ loader = Zeitwerk::Loader.for_gem
17
+ loader.inflector = SwitchmanInflector.new(__FILE__)
18
+ loader.setup
19
+
20
+ module Switchman
21
+ Deprecation = ::ActiveSupport::Deprecation.new("4.0", "Switchman")
22
+
23
+ class << self
24
+ attr_writer :cache
16
25
 
17
- def self.cache=(cache)
18
- @cache = cache
26
+ def config
27
+ # TODO: load from yaml
28
+ @config ||= {}
29
+ end
30
+
31
+ def cache
32
+ (@cache.respond_to?(:call) ? @cache.call : @cache) || ::Rails.cache
33
+ end
34
+
35
+ def region
36
+ config[:region]
37
+ end
38
+
39
+ def foreign_key_check(name, type, limit: nil)
40
+ return unless name.to_s.end_with?("_id") && type.to_s == "integer" && limit.to_i < 8
41
+
42
+ puts <<~TEXT.squish
43
+ WARNING: All foreign keys need to be 8-byte integers.
44
+ #{name} looks like a foreign key.
45
+ If so, please add the option: `:limit => 8`
46
+ TEXT
47
+ end
19
48
  end
20
49
 
21
50
  class OrderOnMultiShardQuery < RuntimeError; end
22
51
  end
52
+
53
+ # Load the engine and everything associated at gem load time
54
+ Switchman::Engine
@@ -2,10 +2,10 @@
2
2
 
3
3
  # In rails 7.0+ if you have only 1 db in the env it doesn't try to do explicit activation
4
4
  # (and for rails purposes we only have one db per env because each database server is a separate env)
5
- if Rails.version < '7.0'
6
- task_prefix = ::Rake::Task.task_defined?('app:db:migrate') ? 'app:db' : 'db'
7
- ::Rake::Task["#{task_prefix}:migrate"].clear_actions.enhance do
8
- ::ActiveRecord::Tasks::DatabaseTasks.migrate
5
+ if Rails.version < "7.0"
6
+ task_prefix = Rake::Task.task_defined?("app:db:migrate") ? "app:db" : "db"
7
+ Rake::Task["#{task_prefix}:migrate"].clear_actions.enhance do
8
+ ActiveRecord::Tasks::DatabaseTasks.migrate
9
9
  # Ensure this doesn't blow up when running inside the dummy app
10
10
  Rake::Task["#{task_prefix}:_dump"].invoke
11
11
  end
@@ -13,28 +13,29 @@ end
13
13
 
14
14
  module Switchman
15
15
  module Rake
16
- def self.filter_database_servers(&block)
17
- chain = filter_database_servers_chain # use a local variable so that the current chain is closed over in the following lambda
18
- @filter_database_servers_chain = ->(servers) { block.call(servers, chain) }
16
+ def self.filter_database_servers
17
+ # use a local variable so that the current chain is closed over in the following lambda
18
+ chain = filter_database_servers_chain
19
+ @filter_database_servers_chain = ->(servers) { yield(servers, chain) }
19
20
  end
20
21
 
21
22
  def self.scope(base_scope = Shard,
22
- database_server: ENV['DATABASE_SERVER'],
23
- shard: ENV['SHARD'])
23
+ database_server: ENV.fetch("DATABASE_SERVER", nil),
24
+ shard: ENV.fetch("SHARD", nil))
24
25
  servers = DatabaseServer.all
25
26
 
26
27
  if database_server
27
28
  servers = database_server
28
- if servers.first == '-'
29
+ if servers.first == "-"
29
30
  negative = true
30
31
  servers = servers[1..]
31
32
  end
32
- servers = servers.split(',')
33
- open = servers.delete('open')
33
+ servers = servers.split(",")
34
+ open = servers.delete("open")
34
35
 
35
- servers = servers.map { |server| DatabaseServer.find(server) }.compact
36
+ servers = servers.filter_map { |server| DatabaseServer.find(server) }
36
37
  if open
37
- open_servers = DatabaseServer.all.select { |server| server.config[:open] }
38
+ open_servers = DatabaseServer.select { |server| server.config[:open] }
38
39
  servers.concat(open_servers)
39
40
  servers << DatabaseServer.find(nil) if open_servers.empty?
40
41
  servers.uniq!
@@ -42,9 +43,22 @@ module Switchman
42
43
  servers = DatabaseServer.all - servers if negative
43
44
  end
44
45
 
46
+ ENV["REGION"]&.split(",")&.each do |region|
47
+ method = :select!
48
+ if region[0] == "-"
49
+ method = :reject!
50
+ region = region[1..]
51
+ end
52
+ if region == "self"
53
+ servers.send(method, &:in_current_region?)
54
+ else
55
+ servers.send(method) { |server| server.in_region?(region) }
56
+ end
57
+ end
58
+
45
59
  servers = filter_database_servers_chain.call(servers)
46
60
 
47
- scope = base_scope.order(::Arel.sql('database_server_id IS NOT NULL, database_server_id, id'))
61
+ scope = base_scope.order(::Arel.sql("database_server_id IS NOT NULL, database_server_id, id"))
48
62
  if servers != DatabaseServer.all
49
63
  database_server_ids = servers.map(&:id)
50
64
  database_server_ids << nil if servers.include?(Shard.default.database_server)
@@ -57,7 +71,7 @@ module Switchman
57
71
  end
58
72
 
59
73
  def self.options
60
- { parallel: ENV['PARALLEL'].to_i }
74
+ { parallel: ENV["PARALLEL"].to_i }
61
75
  end
62
76
 
63
77
  # classes - an array or proc, to activate as the current shard during the
@@ -69,7 +83,7 @@ module Switchman
69
83
 
70
84
  old_task.enhance do |*task_args|
71
85
  if ::Rails.env.test?
72
- require 'switchman/test_helper'
86
+ require "switchman/test_helper"
73
87
  TestHelper.recreate_persistent_test_shards(dont_create: true)
74
88
  end
75
89
 
@@ -86,10 +100,10 @@ module Switchman
86
100
  nil
87
101
  end
88
102
  rescue => e
89
- puts "Exception from #{e.current_shard.id}: #{e.current_shard.description}" if options[:parallel] != 0
103
+ if options[:parallel] != 0
104
+ warn "Exception from #{e.current_shard.id}: #{e.current_shard.description}:\n#{e.full_message}"
105
+ end
90
106
  raise
91
-
92
- # ::ActiveRecord::Base.configurations = old_configurations
93
107
  end
94
108
  end
95
109
  end
@@ -100,7 +114,7 @@ module Switchman
100
114
  end
101
115
 
102
116
  def self.shard_scope(scope, raw_shard_ids)
103
- raw_shard_ids = raw_shard_ids.split(',')
117
+ raw_shard_ids = raw_shard_ids.split(",")
104
118
 
105
119
  shard_ids = []
106
120
  negative_shard_ids = []
@@ -110,13 +124,13 @@ module Switchman
110
124
 
111
125
  raw_shard_ids.each do |id|
112
126
  case id
113
- when 'default'
127
+ when "default"
114
128
  shard_ids << Shard.default.id
115
- when '-default'
129
+ when "-default"
116
130
  negative_shard_ids << Shard.default.id
117
- when 'primary'
131
+ when "primary"
118
132
  shard_ids.concat(Shard.primary.pluck(:id))
119
- when '-primary'
133
+ when "-primary"
120
134
  negative_shard_ids.concat(Shard.primary.pluck(:id))
121
135
  when /^(-?)(\d+)?\.\.(\.)?(\d+)?$/
122
136
  negative, start, open, finish = $1.present?, $2, $3.present?, $4
@@ -124,8 +138,8 @@ module Switchman
124
138
 
125
139
  range = []
126
140
  range << "id>=#{start}" if start
127
- range << "id<#{'=' unless open}#{finish}" if finish
128
- (negative ? negative_ranges : ranges) << "(#{range.join(' AND ')})"
141
+ range << "id<#{"=" unless open}#{finish}" if finish
142
+ (negative ? negative_ranges : ranges) << "(#{range.join(" AND ")})"
129
143
  when /^-(\d+)$/
130
144
  negative_shard_ids << $1.to_i
131
145
  when /^\d+$/
@@ -153,21 +167,21 @@ module Switchman
153
167
  select = []
154
168
  if index != 1
155
169
  subscope = subscope.offset(per_chunk * (index - 1))
156
- select << 'MIN(id) AS min_id'
170
+ select << "MIN(id) AS min_id"
157
171
  end
158
172
  if index != denominator
159
173
  subscope = subscope.limit(per_chunk)
160
- select << 'MAX(id) AS max_id'
174
+ select << "MAX(id) AS max_id"
161
175
  end
162
176
 
163
- result = Shard.from(subscope).select(select.join(', ')).to_a.first
177
+ result = Shard.from(subscope).select(select.join(", ")).to_a.first
164
178
  range = case index
165
179
  when 1
166
- "id<=#{result['max_id']}"
180
+ "id<=#{result["max_id"]}"
167
181
  when denominator
168
- "id>=#{result['min_id']}"
182
+ "id>=#{result["min_id"]}"
169
183
  else
170
- "(id>=#{result['min_id']} AND id<=#{result['max_id']})"
184
+ "(id>=#{result["min_id"]} AND id<=#{result["max_id"]})"
171
185
  end
172
186
 
173
187
  (numerator.negative? ? negative_ranges : ranges) << range
@@ -188,16 +202,16 @@ module Switchman
188
202
 
189
203
  conditions = []
190
204
  positive_queries = []
191
- positive_queries << ranges.join(' OR ') unless ranges.empty?
205
+ positive_queries << ranges.join(" OR ") unless ranges.empty?
192
206
  unless shard_ids.empty?
193
- positive_queries << 'id IN (?)'
207
+ positive_queries << "id IN (?)"
194
208
  conditions << shard_ids
195
209
  end
196
- positive_query = positive_queries.join(' OR ')
210
+ positive_query = positive_queries.join(" OR ")
197
211
  scope = scope.where(positive_query, *conditions) unless positive_queries.empty?
198
212
 
199
- scope = scope.where("NOT (#{negative_ranges.join(' OR')})") unless negative_ranges.empty?
200
- scope = scope.where('id NOT IN (?)', negative_shard_ids) unless negative_shard_ids.empty?
213
+ scope = scope.where("NOT (#{negative_ranges.join(" OR")})") unless negative_ranges.empty?
214
+ scope = scope.where("id NOT IN (?)", negative_shard_ids) unless negative_shard_ids.empty?
201
215
  scope
202
216
  end
203
217
 
@@ -208,21 +222,28 @@ module Switchman
208
222
 
209
223
  module ActiveRecord
210
224
  module PostgreSQLDatabaseTasks
211
- def structure_dump(filename, extra_flags = nil)
212
- set_psql_env
213
- args = ['--schema-only', '--no-privileges', '--no-owner', '--file', filename]
214
- args.concat(Array(extra_flags)) if extra_flags
215
- shard = Shard.current.name
216
- serialized_search_path = shard
217
- args << "--schema=#{Shellwords.escape(shard)}"
218
-
219
- ignore_tables = ::ActiveRecord::SchemaDumper.ignore_tables
220
- args += ignore_tables.flat_map { |table| ['-T', table] } if ignore_tables.any?
221
-
222
- args << db_config.database
223
- run_cmd('pg_dump', args, 'dumping')
224
- remove_sql_header_comments(filename)
225
- File.open(filename, 'a') { |f| f << "SET search_path TO #{serialized_search_path};\n\n" }
225
+ if ::Rails.version < "7.0"
226
+ def structure_dump(filename, extra_flags = nil)
227
+ set_psql_env
228
+ args = ["--schema-only", "--no-privileges", "--no-owner", "--file", filename]
229
+ args.concat(Array(extra_flags)) if extra_flags
230
+ shard = Shard.current.name
231
+ serialized_search_path = shard
232
+ args << "--schema=#{Shellwords.escape(shard)}"
233
+
234
+ ignore_tables = ::ActiveRecord::SchemaDumper.ignore_tables
235
+ args += ignore_tables.flat_map { |table| ["-T", table] } if ignore_tables.any?
236
+
237
+ args << db_config.database
238
+ run_cmd("pg_dump", args, "dumping")
239
+ remove_sql_header_comments(filename)
240
+ File.open(filename, "a") { |f| f << "SET search_path TO #{serialized_search_path};\n\n" }
241
+ end
242
+ else
243
+ def structure_dump(...)
244
+ ::ActiveRecord.dump_schemas = Switchman::Shard.current.name
245
+ super
246
+ end
226
247
  end
227
248
  end
228
249
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: switchman
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.14
4
+ version: 3.5.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
8
8
  - James Williams
9
9
  - Jacob Fugal
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-03-23 00:00:00.000000000 Z
13
+ date: 2024-02-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: 6.1.4
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
- version: '6.2'
24
+ version: '7.2'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
@@ -31,35 +31,35 @@ dependencies:
31
31
  version: 6.1.4
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
- version: '6.2'
34
+ version: '7.2'
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: guardrail
37
37
  requirement: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 3.0.0
41
+ version: 3.0.1
42
42
  type: :runtime
43
43
  prerelease: false
44
44
  version_requirements: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: 3.0.0
48
+ version: 3.0.1
49
49
  - !ruby/object:Gem::Dependency
50
- name: open4
50
+ name: parallel
51
51
  requirement: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: 1.3.0
55
+ version: '1.22'
56
56
  type: :runtime
57
57
  prerelease: false
58
58
  version_requirements: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: 1.3.0
62
+ version: '1.22'
63
63
  - !ruby/object:Gem::Dependency
64
64
  name: railties
65
65
  requirement: !ruby/object:Gem::Requirement
@@ -69,7 +69,7 @@ dependencies:
69
69
  version: '6.1'
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
- version: '6.2'
72
+ version: '7.2'
73
73
  type: :runtime
74
74
  prerelease: false
75
75
  version_requirements: !ruby/object:Gem::Requirement
@@ -79,35 +79,21 @@ dependencies:
79
79
  version: '6.1'
80
80
  - - "<"
81
81
  - !ruby/object:Gem::Version
82
- version: '6.2'
82
+ version: '7.2'
83
83
  - !ruby/object:Gem::Dependency
84
- name: appraisal
84
+ name: debug
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 2.3.0
89
+ version: '1.8'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 2.3.0
97
- - !ruby/object:Gem::Dependency
98
- name: byebug
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
96
+ version: '1.8'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: pg
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -122,20 +108,6 @@ dependencies:
122
108
  - - "~>"
123
109
  - !ruby/object:Gem::Version
124
110
  version: '1.2'
125
- - !ruby/object:Gem::Dependency
126
- name: pry
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
111
  - !ruby/object:Gem::Dependency
140
112
  name: rake
141
113
  requirement: !ruby/object:Gem::Requirement
@@ -170,14 +142,14 @@ dependencies:
170
142
  requirements:
171
143
  - - "~>"
172
144
  - !ruby/object:Gem::Version
173
- version: '4.0'
145
+ version: '6.0'
174
146
  type: :development
175
147
  prerelease: false
176
148
  version_requirements: !ruby/object:Gem::Requirement
177
149
  requirements:
178
150
  - - "~>"
179
151
  - !ruby/object:Gem::Version
180
- version: '4.0'
152
+ version: '6.0'
181
153
  - !ruby/object:Gem::Dependency
182
154
  name: rubocop
183
155
  requirement: !ruby/object:Gem::Requirement
@@ -192,6 +164,20 @@ dependencies:
192
164
  - - "~>"
193
165
  - !ruby/object:Gem::Version
194
166
  version: '1.10'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop-inst
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '1'
195
181
  - !ruby/object:Gem::Dependency
196
182
  name: rubocop-rake
197
183
  requirement: !ruby/object:Gem::Requirement
@@ -242,8 +228,6 @@ extensions: []
242
228
  extra_rdoc_files: []
243
229
  files:
244
230
  - Rakefile
245
- - app/models/switchman/shard.rb
246
- - app/models/switchman/unsharded_record.rb
247
231
  - db/migrate/20130328212039_create_switchman_shards.rb
248
232
  - db/migrate/20130328224244_create_default_shard.rb
249
233
  - db/migrate/20161206323434_add_back_default_string_limits_switchman.rb
@@ -253,10 +237,11 @@ files:
253
237
  - lib/switchman.rb
254
238
  - lib/switchman/action_controller/caching.rb
255
239
  - lib/switchman/active_record/abstract_adapter.rb
256
- - lib/switchman/active_record/association.rb
240
+ - lib/switchman/active_record/associations.rb
257
241
  - lib/switchman/active_record/attribute_methods.rb
258
242
  - lib/switchman/active_record/base.rb
259
243
  - lib/switchman/active_record/calculations.rb
244
+ - lib/switchman/active_record/connection_handler.rb
260
245
  - lib/switchman/active_record/connection_pool.rb
261
246
  - lib/switchman/active_record/database_configurations.rb
262
247
  - lib/switchman/active_record/database_configurations/database_config.rb
@@ -287,12 +272,15 @@ files:
287
272
  - lib/switchman/errors.rb
288
273
  - lib/switchman/guard_rail.rb
289
274
  - lib/switchman/guard_rail/relation.rb
290
- - lib/switchman/open4.rb
275
+ - lib/switchman/parallel.rb
291
276
  - lib/switchman/r_spec_helper.rb
292
277
  - lib/switchman/rails.rb
278
+ - lib/switchman/shard.rb
293
279
  - lib/switchman/sharded_instrumenter.rb
280
+ - lib/switchman/shared_schema_cache.rb
294
281
  - lib/switchman/standard_error.rb
295
282
  - lib/switchman/test_helper.rb
283
+ - lib/switchman/unsharded_record.rb
296
284
  - lib/switchman/version.rb
297
285
  - lib/tasks/switchman.rake
298
286
  homepage: http://www.instructure.com/
@@ -300,7 +288,8 @@ licenses:
300
288
  - MIT
301
289
  metadata:
302
290
  rubygems_mfa_required: 'true'
303
- post_install_message:
291
+ source_code_uri: https://github.com/instructure/switchman
292
+ post_install_message:
304
293
  rdoc_options: []
305
294
  require_paths:
306
295
  - lib
@@ -308,15 +297,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
308
297
  requirements:
309
298
  - - ">="
310
299
  - !ruby/object:Gem::Version
311
- version: '2.6'
300
+ version: '2.7'
312
301
  required_rubygems_version: !ruby/object:Gem::Requirement
313
302
  requirements:
314
303
  - - ">="
315
304
  - !ruby/object:Gem::Version
316
305
  version: '0'
317
306
  requirements: []
318
- rubygems_version: 3.1.4
319
- signing_key:
307
+ rubygems_version: 3.1.6
308
+ signing_key:
320
309
  specification_version: 4
321
310
  summary: Rails sharding magic
322
311
  test_files: []