sequel-schema-sharding 0.12.1 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -1
- data/Rakefile +1 -0
- data/lib/sequel/schema-sharding.rb +9 -0
- data/lib/sequel/schema-sharding/connection_manager.rb +6 -8
- data/lib/sequel/schema-sharding/connection_strategies/primary_with_failover.rb +21 -0
- data/lib/sequel/schema-sharding/connection_strategies/random.rb +16 -0
- data/lib/sequel/schema-sharding/dtrace_provider.rb +1 -1
- data/lib/sequel/schema-sharding/ring.rb +0 -2
- data/lib/sequel/schema-sharding/version.rb +1 -1
- data/lib/sequel/tasks/reset.rake +1 -0
- data/sequel-schema-sharding.gemspec +1 -1
- data/spec/schema-sharding/connection_manager_spec.rb +1 -1
- data/spec/schema-sharding/connection_strategies/primary_with_failover_spec.rb +29 -0
- data/spec/schema-sharding/database_manager_spec.rb +30 -30
- data/spec/schema-sharding/dtrace_provider_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -1
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 925ef9b402dcf173f9cd3a79524b1abe88ff9d46
|
4
|
+
data.tar.gz: 66794b90a0898e0ea70808311acd757eb6fcb252
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a94b17459afdb2d26193fe6910c6174208aa1a3e786fc53e12783e9f5714051b167d8e714b0e6b7468d7ef1dd8c8d833d975d6f0eabaa46700c2bab809747e3d
|
7
|
+
data.tar.gz: de3348153fb3c7bb6e0f7e4752662a410e38c516970b5b56d1772c87bf29476d0aa42a6815888092347d888bf4fee59482d445c90d36a485cd75dd523b8c79f7
|
data/README.md
CHANGED
@@ -131,6 +131,13 @@ local database name.
|
|
131
131
|
See http://sequel.rubyforge.org/rdoc/files/doc/sharding_rdoc.html for more
|
132
132
|
information.
|
133
133
|
|
134
|
+
Note that `sequel-schema-sharding` depends on the `sequel-replica-failover`
|
135
|
+
gem. This means that when making queries to `:read_only` servers (i.e.
|
136
|
+
replicas), certain connection errors will be rescued and re-run against
|
137
|
+
another `:read_only` server. It may be advantageous to include each master
|
138
|
+
database among its replicas, to ensure that read failures on a replica are
|
139
|
+
re-run against the master.
|
140
|
+
|
134
141
|
### Models
|
135
142
|
|
136
143
|
Models declare their table in the class definition. This allows Sequel
|
@@ -203,10 +210,14 @@ queries do not try to reconnect to a downed master.
|
|
203
210
|
|
204
211
|
```bash
|
205
212
|
> bundle install
|
206
|
-
> bundle exec rake
|
213
|
+
> bundle exec rake reset
|
207
214
|
> bundle exec rspec
|
208
215
|
```
|
209
216
|
|
217
|
+
The default max file descriptor limit on Macs is tragically low. If tests
|
218
|
+
fail with `too many open files`, you can run `ulimit -n 2048` to raise the
|
219
|
+
limit.
|
220
|
+
|
210
221
|
## FAQ
|
211
222
|
|
212
223
|
### How should I shard my databases?
|
data/Rakefile
CHANGED
@@ -10,6 +10,7 @@ require 'sequel/schema-sharding/finder'
|
|
10
10
|
require 'sequel/schema-sharding/monkey_patching'
|
11
11
|
require 'sequel/schema-sharding/model'
|
12
12
|
require 'sequel/schema-sharding/logger_proxy'
|
13
|
+
require 'sequel/schema-sharding/connection_strategies/random'
|
13
14
|
|
14
15
|
module Sequel
|
15
16
|
module SchemaSharding
|
@@ -21,6 +22,14 @@ module Sequel
|
|
21
22
|
@config = config
|
22
23
|
end
|
23
24
|
|
25
|
+
def self.replica_strategy
|
26
|
+
@replica_strategy ||= Sequel::SchemaSharding::ConnectionStrategy::Random
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.replica_strategy=(strategy)
|
30
|
+
@replica_strategy = strategy
|
31
|
+
end
|
32
|
+
|
24
33
|
def self.logger
|
25
34
|
@logger ||= Logger.new(nil)
|
26
35
|
end
|
@@ -41,7 +41,6 @@ module Sequel
|
|
41
41
|
# it (ex. %s, %02d).
|
42
42
|
|
43
43
|
def schema_for(table_name, shard_number)
|
44
|
-
number_of_shards = config.number_of_shards(table_name)
|
45
44
|
pattern = config.schema_name(table_name)
|
46
45
|
sprintf pattern, shard_number
|
47
46
|
end
|
@@ -76,15 +75,14 @@ module Sequel
|
|
76
75
|
|
77
76
|
def replica_hash_for(config)
|
78
77
|
return {} if config['replicas'].nil?
|
79
|
-
size = config['replicas'].size
|
80
78
|
{
|
81
|
-
:
|
82
|
-
:
|
83
|
-
|
79
|
+
servers: {
|
80
|
+
read_only: ->(db) {
|
81
|
+
replica_config = Sequel::SchemaSharding.replica_strategy.choose(db, config)
|
84
82
|
probe = Sequel::SchemaSharding::DTraceProvider.provider.replica_hash_for
|
85
|
-
probe.fire(
|
86
|
-
sequel_connection_config_for(
|
87
|
-
|
83
|
+
probe.fire(replica_config.inspect) if probe.enabled?
|
84
|
+
sequel_connection_config_for(replica_config)
|
85
|
+
}
|
88
86
|
}
|
89
87
|
}
|
90
88
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# This strategy is used for choosing a :read_only server
|
2
|
+
# to connect to.
|
3
|
+
#
|
4
|
+
# It will default to the first server in the list. In the event that
|
5
|
+
# the first server is unavailable, the remaining replicas will be
|
6
|
+
# randomly chosen from.
|
7
|
+
module Sequel
|
8
|
+
module SchemaSharding
|
9
|
+
module ConnectionStrategy
|
10
|
+
class PrimaryWithFailover
|
11
|
+
def self.choose(db, config)
|
12
|
+
if db.pool.failing_over?
|
13
|
+
config['replicas'][1..-1].sample
|
14
|
+
else
|
15
|
+
config['replicas'].first
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# This strategy is used for choosing a :read_only server
|
2
|
+
# to connect to.
|
3
|
+
#
|
4
|
+
# A random server will be chosen from the replica list
|
5
|
+
# for this physical shard.
|
6
|
+
module Sequel
|
7
|
+
module SchemaSharding
|
8
|
+
module ConnectionStrategy
|
9
|
+
class Random
|
10
|
+
def self.choose(db, config)
|
11
|
+
config['replicas'].sample
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -14,7 +14,7 @@ module Sequel
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def replica_hash_for
|
17
|
-
@replica_hash_for ||= provider.probe(:connection_manager, :replica_hash_for, :
|
17
|
+
@replica_hash_for ||= provider.probe(:connection_manager, :replica_hash_for, :string)
|
18
18
|
end
|
19
19
|
|
20
20
|
def shard_for
|
@@ -0,0 +1 @@
|
|
1
|
+
task :reset => 'sequel:db:test:reset'
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency 'sequel'
|
22
22
|
spec.add_dependency 'pg'
|
23
|
-
spec.add_dependency 'sequel-replica-failover'
|
23
|
+
spec.add_dependency 'sequel-replica-failover', '>= 2.0.0'
|
24
24
|
spec.add_dependency 'ruby-usdt', '>= 0.2.2'
|
25
25
|
|
26
26
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
@@ -35,7 +35,7 @@ describe Sequel::SchemaSharding::ConnectionManager do
|
|
35
35
|
|
36
36
|
describe "#schema_for" do
|
37
37
|
it "returns the schema name based on env and shard number" do
|
38
|
-
subject.schema_for('boof', 3).
|
38
|
+
expect(subject.schema_for('boof', 3)).to eq 'sequel_logical_boof_03'
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'sequel/schema-sharding/connection_strategies/primary_with_failover'
|
3
|
+
|
4
|
+
describe Sequel::SchemaSharding::ConnectionStrategy::PrimaryWithFailover do
|
5
|
+
let(:db) { stub(pool: stub(failing_over?: failing_over)) }
|
6
|
+
let(:primary) { stub }
|
7
|
+
let(:failover) { stub }
|
8
|
+
let(:config) { {'replicas' => [primary, failover]} }
|
9
|
+
|
10
|
+
subject(:strategy) { Sequel::SchemaSharding::ConnectionStrategy::PrimaryWithFailover }
|
11
|
+
|
12
|
+
describe '.choose' do
|
13
|
+
context 'when primary is not failing' do
|
14
|
+
let(:failing_over) { false }
|
15
|
+
|
16
|
+
it 'returns the primary config' do
|
17
|
+
expect(strategy.choose(db, config)).to eq(primary)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when primary is failing' do
|
22
|
+
let(:failing_over) { true }
|
23
|
+
|
24
|
+
it 'returns a random server that is not primary' do
|
25
|
+
expect(strategy.choose(db, config)).to eq(failover)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -25,11 +25,11 @@ describe Sequel::SchemaSharding::DatabaseManager, type: :manager, sharded: true
|
|
25
25
|
describe '#create_database' do
|
26
26
|
context 'database does not exist' do
|
27
27
|
it 'creates the database for the current environment' do
|
28
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to
|
29
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to
|
28
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to be false
|
29
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to be false
|
30
30
|
@manager.create_databases
|
31
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to
|
32
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to
|
31
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to be true
|
32
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to be true
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -40,12 +40,12 @@ describe Sequel::SchemaSharding::DatabaseManager, type: :manager, sharded: true
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'outputs message to stderr' do
|
43
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to
|
44
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to
|
43
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to be true
|
44
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to be true
|
45
45
|
$stderr.expects(:puts).with(regexp_matches(/already exists/)).twice
|
46
46
|
@manager.create_databases
|
47
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to
|
48
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to
|
47
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to be true
|
48
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to be true
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
@@ -53,23 +53,23 @@ describe Sequel::SchemaSharding::DatabaseManager, type: :manager, sharded: true
|
|
53
53
|
describe '#drop_databases' do
|
54
54
|
context 'databases exist' do
|
55
55
|
it 'drops the database for the current environment' do
|
56
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to
|
57
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to
|
56
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to be false
|
57
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to be false
|
58
58
|
|
59
59
|
@manager.create_databases
|
60
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to
|
61
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to
|
60
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to be true
|
61
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to be true
|
62
62
|
|
63
63
|
@manager.drop_databases
|
64
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to
|
65
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to
|
64
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to be false
|
65
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to be false
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
69
|
context 'databases dont exist' do
|
70
70
|
it 'raises an error' do
|
71
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to
|
72
|
-
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to
|
71
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard1')).to be false
|
72
|
+
expect(DatabaseHelper.db_exists?('sequel_boom_shard2')).to be false
|
73
73
|
|
74
74
|
$stderr.expects(:puts).with(regexp_matches(/database doesnt exist/)).times(2)
|
75
75
|
|
@@ -85,20 +85,20 @@ describe Sequel::SchemaSharding::DatabaseManager, type: :manager, sharded: true
|
|
85
85
|
|
86
86
|
describe '#create_shards' do
|
87
87
|
it 'creates the database structure' do
|
88
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to
|
89
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to
|
88
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to be false
|
89
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to be false
|
90
90
|
@manager.create_shards
|
91
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to
|
92
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to
|
91
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to be true
|
92
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to be true
|
93
93
|
end
|
94
94
|
|
95
95
|
context 'shards already exist' do
|
96
96
|
it 'prints that shards already exist' do
|
97
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to
|
98
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to
|
97
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to be false
|
98
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to be false
|
99
99
|
@manager.create_shards
|
100
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to
|
101
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to
|
100
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to be true
|
101
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to be true
|
102
102
|
|
103
103
|
$stderr.expects(:puts).with(regexp_matches(/already exists/)).at_least_once
|
104
104
|
@manager.create_shards
|
@@ -109,14 +109,14 @@ describe Sequel::SchemaSharding::DatabaseManager, type: :manager, sharded: true
|
|
109
109
|
describe '#drop_schemas' do
|
110
110
|
context 'schemas exist' do
|
111
111
|
it 'drops the schemas' do
|
112
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to
|
113
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to
|
112
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to be false
|
113
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to be false
|
114
114
|
@manager.create_shards
|
115
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to
|
116
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to
|
115
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to be true
|
116
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to be true
|
117
117
|
@manager.drop_shards
|
118
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to
|
119
|
-
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to
|
118
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_boof_01')).to be false
|
119
|
+
expect(DatabaseHelper.schema_exists?('shard1', 'sequel_explosions_artists_01')).to be false
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,7 +8,6 @@ require 'support/database_helper'
|
|
8
8
|
require 'mocha/api'
|
9
9
|
|
10
10
|
RSpec.configure do |config|
|
11
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
12
11
|
config.run_all_when_everything_filtered = true
|
13
12
|
config.filter_run :focus
|
14
13
|
config.alias_example_to :fit, focus: true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel-schema-sharding
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Henry
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-
|
13
|
+
date: 2014-06-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: sequel
|
@@ -46,14 +46,14 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 2.0.0
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
56
|
+
version: 2.0.0
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: ruby-usdt
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +122,8 @@ files:
|
|
122
122
|
- lib/sequel/schema-sharding.rb
|
123
123
|
- lib/sequel/schema-sharding/configuration.rb
|
124
124
|
- lib/sequel/schema-sharding/connection_manager.rb
|
125
|
+
- lib/sequel/schema-sharding/connection_strategies/primary_with_failover.rb
|
126
|
+
- lib/sequel/schema-sharding/connection_strategies/random.rb
|
125
127
|
- lib/sequel/schema-sharding/database_manager.rb
|
126
128
|
- lib/sequel/schema-sharding/database_manager/schema_iterator.rb
|
127
129
|
- lib/sequel/schema-sharding/dtrace_provider.rb
|
@@ -134,6 +136,7 @@ files:
|
|
134
136
|
- lib/sequel/schema-sharding/monkey_patching.rb
|
135
137
|
- lib/sequel/schema-sharding/ring.rb
|
136
138
|
- lib/sequel/schema-sharding/version.rb
|
139
|
+
- lib/sequel/tasks/reset.rake
|
137
140
|
- lib/sequel/tasks/test.rake
|
138
141
|
- sequel-schema-sharding.gemspec
|
139
142
|
- spec/fixtures/db/migrate/artists/001_create_test_table.rb
|
@@ -142,6 +145,7 @@ files:
|
|
142
145
|
- spec/fixtures/test_db_config.yml
|
143
146
|
- spec/schema-sharding/configuration_spec.rb
|
144
147
|
- spec/schema-sharding/connection_manager_spec.rb
|
148
|
+
- spec/schema-sharding/connection_strategies/primary_with_failover_spec.rb
|
145
149
|
- spec/schema-sharding/database_manager/schema_iterator_spec.rb
|
146
150
|
- spec/schema-sharding/database_manager_spec.rb
|
147
151
|
- spec/schema-sharding/dtrace_provider_spec.rb
|
@@ -170,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
174
|
version: '0'
|
171
175
|
requirements: []
|
172
176
|
rubyforge_project:
|
173
|
-
rubygems_version: 2.2.
|
177
|
+
rubygems_version: 2.2.2
|
174
178
|
signing_key:
|
175
179
|
specification_version: 4
|
176
180
|
summary: Create horizontally sharded Sequel models with Postgres
|
@@ -181,6 +185,7 @@ test_files:
|
|
181
185
|
- spec/fixtures/test_db_config.yml
|
182
186
|
- spec/schema-sharding/configuration_spec.rb
|
183
187
|
- spec/schema-sharding/connection_manager_spec.rb
|
188
|
+
- spec/schema-sharding/connection_strategies/primary_with_failover_spec.rb
|
184
189
|
- spec/schema-sharding/database_manager/schema_iterator_spec.rb
|
185
190
|
- spec/schema-sharding/database_manager_spec.rb
|
186
191
|
- spec/schema-sharding/dtrace_provider_spec.rb
|