rails-sharding 1.1.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.ruby-version +1 -1
- data/.travis.yml +1 -1
- data/README.md +26 -10
- data/lib/rails/sharding/active_record_extensions.rb +1 -1
- data/lib/rails/sharding/connection_handler.rb +1 -1
- data/lib/rails/sharding/core.rb +6 -5
- data/lib/rails/sharding/shardable_model.rb +10 -1
- data/lib/rails/sharding/version.rb +1 -1
- data/lib/tasks/rails-sharding.rake +31 -15
- data/rails-sharding.gemspec +4 -4
- metadata +11 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b567029d770be424e7c1141bd5f483fd5fee49a630ee31248d66af9d57976ab9
|
4
|
+
data.tar.gz: 0aa3dd59efebe3aba5949784fcd342d3595dbe719057db9a68341480d3dae9bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88089653b9b9c99acb012872175d426d5b60aad54b7e65a2d98afb6b128c7b7a1e904cdc62d06db1d68bd4c3d2589d1ed5cc7e6537d9ced97bc2f9e0044ba35b
|
7
|
+
data.tar.gz: 338d7f533b28c46625a0102cc861932a8819bde1084a02b37cf8a7ae1593b948bd35aefc6b0c5355967399453a70232f28bb465aaefdb86aaf2fe965c1d3b4c1
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.5.7
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -8,28 +8,34 @@
|
|
8
8
|
|
9
9
|
Simple and robust sharding gem for Rails, including Migrations and ActiveRecord extensions
|
10
10
|
|
11
|
-
This gems allows you to easily create extra databases to your rails application, and freely allocate ActiveRecord instances to any of the databases.
|
11
|
+
This gems allows you to easily create extra databases to your rails application, and freely allocate ActiveRecord instances to any of the databases.
|
12
12
|
|
13
|
-
|
13
|
+
Accessing shards is as simple as:
|
14
14
|
```ruby
|
15
|
+
# creating a user to a specific shard
|
15
16
|
new_user = User.using_shard(:shard_group1, :shard1).create(username: 'x')
|
17
|
+
|
18
|
+
# retrieving a user from a specific shard
|
16
19
|
loaded_user = User.using_shard(:shard_group1, :shard1).where(username: 'x').first
|
17
20
|
```
|
18
21
|
|
19
|
-
You can also use the block syntax
|
22
|
+
You can also use the block syntax:
|
20
23
|
```ruby
|
21
24
|
Rails::Sharding.using_shard(:shard_group1, :shard1) do
|
25
|
+
# All statements inside this block will go to the selected shard
|
26
|
+
|
27
|
+
# Do some queries
|
22
28
|
new_user = User.create(username: 'x')
|
23
29
|
loaded_user = User.where(username: 'x').first
|
24
30
|
billing_infos = loaded_user.billing_infos.all
|
25
31
|
end
|
26
32
|
```
|
27
33
|
|
28
|
-
You can also pick and choose which models will be shardable
|
34
|
+
You can also pick and choose which models will be shardable. Non shardable models will be retrieved from the master database, even if inside a `using_shard` block.
|
29
35
|
|
30
36
|
## Compatibility
|
31
37
|
Gem version 1.x.x:
|
32
|
-
* Rails 5.0
|
38
|
+
* Rails 5.0, 5.1 and 5.2
|
33
39
|
* Databases: MySQL, MariaDB, Postgres
|
34
40
|
|
35
41
|
Gem version 0.x.x:
|
@@ -51,7 +57,6 @@ bundle
|
|
51
57
|
```
|
52
58
|
|
53
59
|
## Creating Shards
|
54
|
-
This gem helps you create shards that are additional and completely separate from your master database. The master database is the one that is created and managed through rails, and is the default storage for all your models.
|
55
60
|
|
56
61
|
To start with the rails-sharding gem, run the command
|
57
62
|
```
|
@@ -80,7 +85,9 @@ development:
|
|
80
85
|
...
|
81
86
|
```
|
82
87
|
|
83
|
-
Rename it to `config/shards.yml` and change it to your database configuration. This example file defines a single shard group (named `shard_group1`) containing two shards (`shard1` and `shard2`).
|
88
|
+
Rename it to `config/shards.yml` and change it to your database configuration. This example file defines a single shard group (named `shard_group1`) containing two shards (`shard1` and `shard2`).
|
89
|
+
|
90
|
+
**A shard group is a set of shards that should have the same schema.**
|
84
91
|
|
85
92
|
When you're ready to create the shards run
|
86
93
|
```
|
@@ -88,7 +95,13 @@ rake shards:create
|
|
88
95
|
```
|
89
96
|
|
90
97
|
## Migrating Shards
|
91
|
-
Go to the directory `db/shards_migrations/shard_group1` and add all migrations that you want to run on the shards of `shard_group1`. By design, all shards in a same group should always have the same schema.
|
98
|
+
Go to the directory `db/shards_migrations/shard_group1` and add all migrations that you want to run on the shards of `shard_group1`. By design, all shards in a same group should always have the same schema.
|
99
|
+
|
100
|
+
|
101
|
+
As of now, there is no generator for migrations. You can use the regular rails generator and move the migrations to the `shards_migration` folder.
|
102
|
+
|
103
|
+
|
104
|
+
For example, add the following migration to your `db/shards_migrations/shard_group1`:
|
92
105
|
```ruby
|
93
106
|
# 20160808000000_create_users.rb
|
94
107
|
class CreateClients < ActiveRecord::Migration[5.0]
|
@@ -175,15 +188,18 @@ Rails::Sharding.setup do |config|
|
|
175
188
|
end
|
176
189
|
```
|
177
190
|
|
191
|
+
## Wiki
|
192
|
+
Want to know more? How to integrate with RSpec, Capistrano, etc? Take a look at our [wiki](https://github.com/hsgubert/rails-sharding/wiki).
|
193
|
+
|
178
194
|
## Development and Contributing
|
179
195
|
|
180
196
|
After checking out the repo:
|
181
197
|
|
182
|
-
1. Run `bundle` to install gems
|
198
|
+
1. Run `bundle` to install gems
|
183
199
|
|
184
200
|
1. Create your `spec/fixtures/shards.yml` based on the example on this same folder (you need MySQL and Postgres)
|
185
201
|
|
186
|
-
1. Run `rake db:test:prepare` to create the test shards.
|
202
|
+
1. Run `rake db:test:prepare` to create the test shards.
|
187
203
|
|
188
204
|
1. Run `rspec` to run the tests.
|
189
205
|
|
@@ -78,7 +78,7 @@ module Rails::Sharding
|
|
78
78
|
alias_method :eql?, :==
|
79
79
|
end
|
80
80
|
|
81
|
-
# Fixes case
|
81
|
+
# Fixes case-when behavior when ScopeProxy is passed to case
|
82
82
|
# (otherwise classes don't match)
|
83
83
|
module CaseFixer
|
84
84
|
def ===(other)
|
@@ -78,7 +78,7 @@ module Rails::Sharding
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def self.with_connection(shard_group, shard_name, &block)
|
81
|
-
|
81
|
+
connection_pool(shard_group, shard_name).with_connection do |connection|
|
82
82
|
if connection && Config.add_shard_tag_to_query_logs
|
83
83
|
connection_name = connection_name(shard_group, shard_name)
|
84
84
|
add_shard_tag_to_connection_log(connection, connection_name)
|
data/lib/rails/sharding/core.rb
CHANGED
@@ -13,10 +13,11 @@ module Rails::Sharding
|
|
13
13
|
ShardThreadRegistry.push_current_shard(shard_group, shard_name)
|
14
14
|
yield
|
15
15
|
ensure
|
16
|
+
was_connected_to_master = ShardThreadRegistry.connecting_to_master?
|
16
17
|
shard_group, shard_name, connection_used = ShardThreadRegistry.pop_current_shard
|
17
18
|
|
18
|
-
# shows warning to user
|
19
|
-
if Config.no_connection_retrieved_warning && !connection_used
|
19
|
+
# shows warning to user (except when connected to master database)
|
20
|
+
if Config.no_connection_retrieved_warning && !connection_used && !was_connected_to_master
|
20
21
|
puts "Warning: no connection to shard '#{shard_group}:#{shard_name}' was retrieved inside the using_shard block. Make sure you don't forget to include Rails::Sharding::ShardableModel to the models you want to be sharded. Disable this warning with Rails::Sharding::Config.no_connection_retrieved_warning = false."
|
21
22
|
end
|
22
23
|
|
@@ -32,7 +33,7 @@ module Rails::Sharding
|
|
32
33
|
environment_config = @@db_configs[environment]
|
33
34
|
return environment_config if environment_config
|
34
35
|
|
35
|
-
raise Errors::ConfigNotFoundError, 'Found no shard configurations for
|
36
|
+
raise Errors::ConfigNotFoundError, 'Found no shard configurations for environment "' + environment + '" in ' + Config.shards_config_file.to_s + ' file was not found'
|
36
37
|
rescue Errno::ENOENT
|
37
38
|
raise Errors::ConfigNotFoundError, Config.shards_config_file.to_s + ' file was not found'
|
38
39
|
end
|
@@ -56,11 +57,11 @@ module Rails::Sharding
|
|
56
57
|
# yields a block for each shard in each shard group, with its configurations
|
57
58
|
# shard_group_filter: if passed yields only shards of this group
|
58
59
|
# shard_name_filter: if passed yields only shards with this name
|
59
|
-
def self.for_each_shard(shard_group_filter
|
60
|
+
def self.for_each_shard(environment:Rails.env, shard_group_filter:nil, shard_name_filter:nil)
|
60
61
|
shard_group_filter.to_s if shard_group_filter
|
61
62
|
shard_name_filter.to_s if shard_name_filter
|
62
63
|
|
63
|
-
configurations.each do |shard_group, shards_configurations|
|
64
|
+
configurations(environment).each do |shard_group, shards_configurations|
|
64
65
|
next if shard_group_filter && shard_group_filter != shard_group.to_s
|
65
66
|
|
66
67
|
shards_configurations.each do |shard, configuration|
|
@@ -52,7 +52,7 @@ module Rails::Sharding
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
# @overrides ActiveRecord::ConnectionHandling#
|
55
|
+
# @overrides ActiveRecord::ConnectionHandling#connected?
|
56
56
|
def sharded_connected?
|
57
57
|
if ShardThreadRegistry.connecting_to_master?
|
58
58
|
return original_connected?
|
@@ -107,6 +107,15 @@ module Rails::Sharding
|
|
107
107
|
return ConnectionHandler.connection_handler.clear_all_connections!
|
108
108
|
end
|
109
109
|
end
|
110
|
+
|
111
|
+
# @overrides ActiveRecord::ConnectionHandling#flush_idle_connections!
|
112
|
+
def sharded_flush_idle_connections!
|
113
|
+
if ShardThreadRegistry.connecting_to_master?
|
114
|
+
return original_flush_idle_connections!
|
115
|
+
else
|
116
|
+
return ConnectionHandler.connection_handler.flush_idle_connections!
|
117
|
+
end
|
118
|
+
end
|
110
119
|
end
|
111
120
|
|
112
121
|
end
|
@@ -27,25 +27,32 @@ shards_namespace = namespace :shards do
|
|
27
27
|
|
28
28
|
desc "Creates database shards (options: RAILS_ENV=x SHARD_GROUP=x SHARD=x)"
|
29
29
|
task create: [:environment] do
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
# creates DB for both development and test envs, when in development
|
31
|
+
each_current_environment do |environment|
|
32
|
+
Rails::Sharding.for_each_shard(environment: environment, shard_group_filter: ENV["SHARD_GROUP"], shard_name_filter: ENV["SHARD"]) do |shard_group, shard, configuration|
|
33
|
+
puts "== Creating shard #{shard_group}:#{shard}"
|
34
|
+
|
35
|
+
ActiveRecord::Tasks::DatabaseTasks.create(configuration)
|
36
|
+
end
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
36
40
|
desc "Drops database shards (options: RAILS_ENV=x SHARD_GROUP=x SHARD=x)"
|
37
41
|
task drop: [:environment, :check_protected_environments] do
|
38
|
-
|
39
|
-
|
42
|
+
# drops DB for both development and test envs, when in development
|
43
|
+
each_current_environment do |environment|
|
44
|
+
Rails::Sharding.for_each_shard(shard_group_filter: ENV["SHARD_GROUP"], shard_name_filter: ENV["SHARD"]) do |shard_group, shard, configuration|
|
45
|
+
puts "== Dropping shard #{shard_group}:#{shard}"
|
40
46
|
|
41
|
-
|
42
|
-
|
47
|
+
# closes connections with shard before dropping (postgres requires this, mysql does not but there is no harm)
|
48
|
+
Rails::Sharding::ConnectionHandler.remove_connection(shard_group, shard)
|
43
49
|
|
44
|
-
|
50
|
+
ActiveRecord::Tasks::DatabaseTasks.drop(configuration)
|
45
51
|
|
46
|
-
|
47
|
-
|
48
|
-
|
52
|
+
# reestablishes connection (because we removed before). You can do this even if the database does not exist yet,
|
53
|
+
# you just cannot retrieve the connection yet.
|
54
|
+
Rails::Sharding::ConnectionHandler.establish_connection(shard_group, shard)
|
55
|
+
end
|
49
56
|
end
|
50
57
|
end
|
51
58
|
|
@@ -91,7 +98,7 @@ shards_namespace = namespace :shards do
|
|
91
98
|
task dump: [:_make_activerecord_base_shardable] do
|
92
99
|
require "active_record/schema_dumper"
|
93
100
|
|
94
|
-
Rails::Sharding.for_each_shard(ENV["SHARD_GROUP"], ENV["SHARD"]) do |shard_group, shard, _configuration|
|
101
|
+
Rails::Sharding.for_each_shard(shard_group_filter: ENV["SHARD_GROUP"], shard_name_filter: ENV["SHARD"]) do |shard_group, shard, _configuration|
|
95
102
|
puts "== Dumping schema of #{shard_group}:#{shard}"
|
96
103
|
|
97
104
|
schema_filename = shard_schema_path(shard_group, shard)
|
@@ -216,7 +223,7 @@ shards_namespace = namespace :shards do
|
|
216
223
|
|
217
224
|
desc "Retrieves the current schema version number"
|
218
225
|
task version: [:_make_activerecord_base_shardable] do
|
219
|
-
Rails::Sharding.for_each_shard(ENV["SHARD_GROUP"], ENV["SHARD"]) do |shard_group, shard, _configuration|
|
226
|
+
Rails::Sharding.for_each_shard(shard_group_filter: ENV["SHARD_GROUP"], shard_name_filter: ENV["SHARD"]) do |shard_group, shard, _configuration|
|
220
227
|
Rails::Sharding.using_shard(shard_group, shard) do
|
221
228
|
puts "Shard #{shard_group}:#{shard} version: #{ActiveRecord::Migrator.current_version}"
|
222
229
|
end
|
@@ -273,8 +280,8 @@ shards_namespace = namespace :shards do
|
|
273
280
|
end
|
274
281
|
|
275
282
|
desc "Empty the test shards (drops all tables) (options: SHARD_GROUP=x, SHARD=x)"
|
276
|
-
task :
|
277
|
-
Rails::Sharding.for_each_shard(ENV["SHARD_GROUP"], ENV["SHARD"]) do |shard_group, shard, configuration|
|
283
|
+
task purge: [:_make_activerecord_base_shardable] do
|
284
|
+
Rails::Sharding.for_each_shard(environment: 'test', shard_group_filter: ENV["SHARD_GROUP"], shard_name_filter: ENV["SHARD"]) do |shard_group, shard, configuration|
|
278
285
|
puts "== Purging test shard #{shard_group}:#{shard}"
|
279
286
|
begin
|
280
287
|
# establishes connection with test shard, saving if it was connected before (rails 4.2 doesn't do this, but should)
|
@@ -316,4 +323,13 @@ shards_namespace = namespace :shards do
|
|
316
323
|
raise error_message unless version
|
317
324
|
version
|
318
325
|
end
|
326
|
+
|
327
|
+
def each_current_environment
|
328
|
+
environments = [Rails.env]
|
329
|
+
environments << "test" if environments == ["development"]
|
330
|
+
|
331
|
+
environments.each do |env|
|
332
|
+
yield env
|
333
|
+
end
|
334
|
+
end
|
319
335
|
end
|
data/rails-sharding.gemspec
CHANGED
@@ -23,12 +23,12 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
24
|
spec.require_paths = ["lib"]
|
25
25
|
|
26
|
-
spec.add_runtime_dependency 'rails', '~> 5.
|
26
|
+
spec.add_runtime_dependency 'rails', '~> 5.2.0'
|
27
27
|
|
28
|
-
spec.add_development_dependency "bundler", "~> 1.
|
29
|
-
spec.add_development_dependency "rake", "~>
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
29
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
30
30
|
spec.add_development_dependency "rspec", "~> 3.0"
|
31
|
-
spec.add_development_dependency "byebug", '~>
|
31
|
+
spec.add_development_dependency "byebug", '~> 11'
|
32
32
|
spec.add_development_dependency "mysql2", '~> 0'
|
33
33
|
spec.add_development_dependency "pg", '~> 0' # postgres driver
|
34
34
|
spec.add_development_dependency "codeclimate-test-reporter", '~> 1'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-sharding
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henrique Gubert
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.
|
19
|
+
version: 5.2.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.
|
26
|
+
version: 5.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.17'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.17'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '13.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '13.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '11'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '11'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: mysql2
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -193,8 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '0'
|
195
195
|
requirements: []
|
196
|
-
|
197
|
-
rubygems_version: 2.6.11
|
196
|
+
rubygems_version: 3.0.6
|
198
197
|
signing_key:
|
199
198
|
specification_version: 4
|
200
199
|
summary: Simple and robust sharding for Rails, including Migrations and ActiveRecord
|