ar-octopus-ruby-3 0.11.2

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 (160) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +46 -0
  5. data/.rubocop_todo.yml +56 -0
  6. data/.travis.yml +18 -0
  7. data/Appraisals +16 -0
  8. data/Gemfile +4 -0
  9. data/README.mkdn +257 -0
  10. data/Rakefile +175 -0
  11. data/TODO.txt +7 -0
  12. data/ar-octopus.gemspec +44 -0
  13. data/gemfiles/rails42.gemfile +7 -0
  14. data/gemfiles/rails5.gemfile +7 -0
  15. data/gemfiles/rails51.gemfile +7 -0
  16. data/gemfiles/rails52.gemfile +7 -0
  17. data/lib/ar-octopus.rb +1 -0
  18. data/lib/octopus/abstract_adapter.rb +33 -0
  19. data/lib/octopus/association.rb +14 -0
  20. data/lib/octopus/association_shard_tracking.rb +74 -0
  21. data/lib/octopus/collection_association.rb +17 -0
  22. data/lib/octopus/collection_proxy.rb +16 -0
  23. data/lib/octopus/exception.rb +4 -0
  24. data/lib/octopus/finder_methods.rb +8 -0
  25. data/lib/octopus/load_balancing/round_robin.rb +20 -0
  26. data/lib/octopus/load_balancing.rb +4 -0
  27. data/lib/octopus/log_subscriber.rb +26 -0
  28. data/lib/octopus/migration.rb +236 -0
  29. data/lib/octopus/model.rb +216 -0
  30. data/lib/octopus/persistence.rb +45 -0
  31. data/lib/octopus/proxy.rb +399 -0
  32. data/lib/octopus/proxy_config.rb +251 -0
  33. data/lib/octopus/query_cache_for_shards.rb +24 -0
  34. data/lib/octopus/railtie.rb +11 -0
  35. data/lib/octopus/relation_proxy.rb +74 -0
  36. data/lib/octopus/result_patch.rb +19 -0
  37. data/lib/octopus/scope_proxy.rb +68 -0
  38. data/lib/octopus/shard_tracking/attribute.rb +22 -0
  39. data/lib/octopus/shard_tracking/dynamic.rb +11 -0
  40. data/lib/octopus/shard_tracking.rb +46 -0
  41. data/lib/octopus/singular_association.rb +9 -0
  42. data/lib/octopus/slave_group.rb +13 -0
  43. data/lib/octopus/version.rb +3 -0
  44. data/lib/octopus.rb +209 -0
  45. data/lib/tasks/octopus.rake +16 -0
  46. data/sample_app/.gitignore +4 -0
  47. data/sample_app/.rspec +1 -0
  48. data/sample_app/Gemfile +20 -0
  49. data/sample_app/Gemfile.lock +155 -0
  50. data/sample_app/README +3 -0
  51. data/sample_app/README.rdoc +261 -0
  52. data/sample_app/Rakefile +7 -0
  53. data/sample_app/app/assets/images/rails.png +0 -0
  54. data/sample_app/app/assets/javascripts/application.js +15 -0
  55. data/sample_app/app/assets/stylesheets/application.css +13 -0
  56. data/sample_app/app/controllers/application_controller.rb +4 -0
  57. data/sample_app/app/helpers/application_helper.rb +2 -0
  58. data/sample_app/app/mailers/.gitkeep +0 -0
  59. data/sample_app/app/models/.gitkeep +0 -0
  60. data/sample_app/app/models/item.rb +3 -0
  61. data/sample_app/app/models/user.rb +3 -0
  62. data/sample_app/app/views/layouts/application.html.erb +14 -0
  63. data/sample_app/autotest/discover.rb +2 -0
  64. data/sample_app/config/application.rb +62 -0
  65. data/sample_app/config/boot.rb +6 -0
  66. data/sample_app/config/cucumber.yml +8 -0
  67. data/sample_app/config/database.yml +28 -0
  68. data/sample_app/config/environment.rb +5 -0
  69. data/sample_app/config/environments/development.rb +37 -0
  70. data/sample_app/config/environments/production.rb +67 -0
  71. data/sample_app/config/environments/test.rb +37 -0
  72. data/sample_app/config/initializers/backtrace_silencers.rb +7 -0
  73. data/sample_app/config/initializers/inflections.rb +15 -0
  74. data/sample_app/config/initializers/mime_types.rb +5 -0
  75. data/sample_app/config/initializers/secret_token.rb +7 -0
  76. data/sample_app/config/initializers/session_store.rb +8 -0
  77. data/sample_app/config/initializers/wrap_parameters.rb +14 -0
  78. data/sample_app/config/locales/en.yml +5 -0
  79. data/sample_app/config/routes.rb +58 -0
  80. data/sample_app/config/shards.yml +28 -0
  81. data/sample_app/config.ru +4 -0
  82. data/sample_app/db/migrate/20100720172715_create_users.rb +15 -0
  83. data/sample_app/db/migrate/20100720172730_create_items.rb +16 -0
  84. data/sample_app/db/migrate/20100720210335_create_sample_users.rb +11 -0
  85. data/sample_app/db/schema.rb +29 -0
  86. data/sample_app/db/seeds.rb +16 -0
  87. data/sample_app/doc/README_FOR_APP +2 -0
  88. data/sample_app/features/migrate.feature +45 -0
  89. data/sample_app/features/seed.feature +15 -0
  90. data/sample_app/features/step_definitions/seeds_steps.rb +13 -0
  91. data/sample_app/features/step_definitions/web_steps.rb +218 -0
  92. data/sample_app/features/support/database.rb +13 -0
  93. data/sample_app/features/support/env.rb +57 -0
  94. data/sample_app/features/support/paths.rb +33 -0
  95. data/sample_app/lib/assets/.gitkeep +0 -0
  96. data/sample_app/lib/tasks/.gitkeep +0 -0
  97. data/sample_app/lib/tasks/cucumber.rake +64 -0
  98. data/sample_app/log/.gitkeep +0 -0
  99. data/sample_app/public/404.html +26 -0
  100. data/sample_app/public/422.html +26 -0
  101. data/sample_app/public/500.html +26 -0
  102. data/sample_app/public/favicon.ico +0 -0
  103. data/sample_app/public/images/rails.png +0 -0
  104. data/sample_app/public/index.html +279 -0
  105. data/sample_app/public/javascripts/application.js +2 -0
  106. data/sample_app/public/javascripts/controls.js +965 -0
  107. data/sample_app/public/javascripts/dragdrop.js +974 -0
  108. data/sample_app/public/javascripts/effects.js +1123 -0
  109. data/sample_app/public/javascripts/prototype.js +4874 -0
  110. data/sample_app/public/javascripts/rails.js +118 -0
  111. data/sample_app/public/robots.txt +5 -0
  112. data/sample_app/public/stylesheets/.gitkeep +0 -0
  113. data/sample_app/script/cucumber +10 -0
  114. data/sample_app/script/rails +6 -0
  115. data/sample_app/spec/models/item_spec.rb +5 -0
  116. data/sample_app/spec/models/user_spec.rb +5 -0
  117. data/sample_app/spec/spec_helper.rb +27 -0
  118. data/sample_app/vendor/assets/javascripts/.gitkeep +0 -0
  119. data/sample_app/vendor/assets/stylesheets/.gitkeep +0 -0
  120. data/sample_app/vendor/plugins/.gitkeep +0 -0
  121. data/spec/config/shards.yml +231 -0
  122. data/spec/migrations/10_create_users_using_replication.rb +9 -0
  123. data/spec/migrations/11_add_field_in_all_slaves.rb +11 -0
  124. data/spec/migrations/12_create_users_using_block.rb +23 -0
  125. data/spec/migrations/13_create_users_using_block_and_using.rb +15 -0
  126. data/spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb +11 -0
  127. data/spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb +9 -0
  128. data/spec/migrations/1_create_users_on_master.rb +9 -0
  129. data/spec/migrations/2_create_users_on_canada.rb +11 -0
  130. data/spec/migrations/3_create_users_on_both_shards.rb +11 -0
  131. data/spec/migrations/4_create_users_on_shards_of_a_group.rb +11 -0
  132. data/spec/migrations/5_create_users_on_multiples_groups.rb +11 -0
  133. data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +11 -0
  134. data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +11 -0
  135. data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +11 -0
  136. data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +11 -0
  137. data/spec/octopus/association_shard_tracking_spec.rb +1036 -0
  138. data/spec/octopus/collection_proxy_spec.rb +16 -0
  139. data/spec/octopus/load_balancing/round_robin_spec.rb +15 -0
  140. data/spec/octopus/log_subscriber_spec.rb +19 -0
  141. data/spec/octopus/migration_spec.rb +151 -0
  142. data/spec/octopus/model_spec.rb +837 -0
  143. data/spec/octopus/octopus_spec.rb +123 -0
  144. data/spec/octopus/proxy_spec.rb +303 -0
  145. data/spec/octopus/query_cache_for_shards_spec.rb +40 -0
  146. data/spec/octopus/relation_proxy_spec.rb +132 -0
  147. data/spec/octopus/replicated_slave_grouped_spec.rb +91 -0
  148. data/spec/octopus/replication_spec.rb +196 -0
  149. data/spec/octopus/scope_proxy_spec.rb +97 -0
  150. data/spec/octopus/sharded_replicated_slave_grouped_spec.rb +55 -0
  151. data/spec/octopus/sharded_spec.rb +33 -0
  152. data/spec/spec_helper.rb +18 -0
  153. data/spec/support/active_record/connection_adapters/modify_config_adapter.rb +15 -0
  154. data/spec/support/database_connection.rb +4 -0
  155. data/spec/support/database_models.rb +118 -0
  156. data/spec/support/octopus_helper.rb +66 -0
  157. data/spec/support/query_count.rb +17 -0
  158. data/spec/support/shared_contexts.rb +18 -0
  159. data/spec/tasks/octopus.rake_spec.rb +32 -0
  160. metadata +351 -0
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Octopus::CollectionProxy do
4
+ describe 'method dispatch' do
5
+ before :each do
6
+ @client = Client.using(:canada).create!
7
+ @client.items << Item.using(:canada).create!
8
+ end
9
+
10
+ it 'computes the size of the collection without loading it' do
11
+ expect(@client.items.size).to eq(1)
12
+
13
+ expect(@client.items.loaded?).to be false
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Octopus::LoadBalancing::RoundRobin do
4
+ it "raises an error when no shards are given" do
5
+ expect do
6
+ Octopus::LoadBalancing::RoundRobin.new([])
7
+ end.to raise_error Octopus::Exception
8
+ end
9
+
10
+ it "does not raise an error if slaves given" do
11
+ expect do
12
+ Octopus::LoadBalancing::RoundRobin.new([:stub])
13
+ end.to_not raise_error Octopus::Exception
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Octopus::LogSubscriber, :shards => [:canada] do
4
+ before :each do
5
+ @out = StringIO.new
6
+ @log = Logger.new(@out)
7
+ ActiveRecord::Base.logger = @log
8
+ ActiveRecord::Base.logger.level = Logger::DEBUG
9
+ end
10
+
11
+ after :each do
12
+ ActiveRecord::Base.logger = Logger.new(File.open('database.log', 'a'))
13
+ end
14
+
15
+ it 'should add to the default logger the shard name the query was sent to' do
16
+ User.using(:canada).create!(:name => 'test')
17
+ expect(@out.string).to match(/Shard: canada/)
18
+ end
19
+ end
@@ -0,0 +1,151 @@
1
+ require 'spec_helper'
2
+
3
+ def get_all_versions
4
+ if Octopus.atleast_rails52?
5
+ schema = ActiveRecord::SchemaMigration
6
+ migrations_root = File.expand_path(File.join(File.dirname(__FILE__), '..', 'migrations'))
7
+
8
+ ActiveRecord::MigrationContext.new(migrations_root, schema).get_all_versions
9
+ else
10
+ ActiveRecord::Migrator.get_all_versions
11
+ end
12
+ end
13
+
14
+ describe Octopus::Migration do
15
+ it 'should run just in the master shard' do
16
+ OctopusHelper.migrating_to_version 1 do
17
+ expect(User.using(:master).find_by_name('Master')).not_to be_nil
18
+ expect(User.using(:canada).find_by_name('Master')).to be_nil
19
+ end
20
+ end
21
+
22
+ it 'should run on specific shard' do
23
+ OctopusHelper.migrating_to_version 2 do
24
+ expect(User.using(:master).find_by_name('Sharding')).to be_nil
25
+ expect(User.using(:canada).find_by_name('Sharding')).not_to be_nil
26
+ end
27
+ end
28
+
29
+ it 'should run on specifieds shards' do
30
+ OctopusHelper.migrating_to_version 3 do
31
+ expect(User.using(:brazil).find_by_name('Both')).not_to be_nil
32
+ expect(User.using(:canada).find_by_name('Both')).not_to be_nil
33
+ end
34
+ end
35
+
36
+ it 'should run on specified group' do
37
+ OctopusHelper.migrating_to_version 4 do
38
+ expect(User.using(:canada).find_by_name('Group')).not_to be_nil
39
+ expect(User.using(:brazil).find_by_name('Group')).not_to be_nil
40
+ expect(User.using(:russia).find_by_name('Group')).not_to be_nil
41
+ end
42
+ end
43
+
44
+ it "should rollback correctly migrations" do
45
+ migrations_root = File.expand_path(File.join(File.dirname(__FILE__), '..', 'migrations'))
46
+ if Octopus.atleast_rails52?
47
+ OctopusHelper.migrate_to_version(:up, migrations_root, 4)
48
+ else
49
+ ActiveRecord::Migrator.run(:up, migrations_root, 4)
50
+ end
51
+
52
+ expect(User.using(:canada).find_by_name('Group')).not_to be_nil
53
+ expect(User.using(:brazil).find_by_name('Group')).not_to be_nil
54
+ expect(User.using(:russia).find_by_name('Group')).not_to be_nil
55
+
56
+
57
+ Octopus.using(:canada) do
58
+ if Octopus.atleast_rails52?
59
+ OctopusHelper.migrate_to_version(:down, migrations_root, 4)
60
+ else
61
+ ActiveRecord::Migrator.rollback(migrations_root, 4)
62
+ end
63
+ end
64
+
65
+ expect(User.using(:canada).find_by_name('Group')).to be_nil
66
+ expect(User.using(:brazil).find_by_name('Group')).to be_nil
67
+ expect(User.using(:russia).find_by_name('Group')).to be_nil
68
+ end
69
+
70
+ it 'should run once per shard' do
71
+ OctopusHelper.migrating_to_version 5 do
72
+ expect(User.using(:canada).where(:name => 'MultipleGroup').size).to eq(1)
73
+ expect(User.using(:brazil).where(:name => 'MultipleGroup').size).to eq(1)
74
+ expect(User.using(:russia).where(:name => 'MultipleGroup').size).to eq(1)
75
+ end
76
+ end
77
+
78
+ it 'should create users inside block' do
79
+ OctopusHelper.migrating_to_version 12 do
80
+ expect(User.using(:brazil).where(:name => 'UsingBlock1').size).to eq(1)
81
+ expect(User.using(:brazil).where(:name => 'UsingBlock2').size).to eq(1)
82
+ expect(User.using(:canada).where(:name => 'UsingCanada').size).to eq(1)
83
+ expect(User.using(:canada).where(:name => 'UsingCanada2').size).to eq(1)
84
+ end
85
+ end
86
+
87
+ it 'should send the query to the correct shard' do
88
+ OctopusHelper.migrating_to_version 13 do
89
+ expect(User.using(:brazil).where(:name => 'Brazil').size).to eq(1)
90
+ expect(User.using(:brazil).where(:name => 'Canada').size).to eq(0)
91
+ expect(User.using(:canada).where(:name => 'Brazil').size).to eq(0)
92
+ expect(User.using(:canada).where(:name => 'Canada').size).to eq(1)
93
+ end
94
+ end
95
+
96
+ describe 'when using replication' do
97
+ it 'should run writes on master when you use replication' do
98
+ OctopusHelper.using_environment :production_replicated do
99
+ OctopusHelper.migrating_to_version 10 do
100
+ expect(Cat.find_by_name('Replication')).to be_nil
101
+ end
102
+ end
103
+ end
104
+
105
+ it 'should run in all shards, master or another shards' do
106
+ OctopusHelper.using_environment :production_replicated do
107
+ OctopusHelper.migrating_to_version 11 do
108
+ [:slave4, :slave1, :slave2, :slave3].each do |_sym|
109
+ expect(Cat.find_by_name('Slaves')).not_to be_nil
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ it 'should store the migration versions in each shard' do
117
+ class SchemaMigration < ActiveRecord::Base; end
118
+
119
+ OctopusHelper.migrating_to_version 14 do
120
+ expect(Octopus.using(:canada) { get_all_versions }).to include(14)
121
+ expect(Octopus.using(:brazil) { get_all_versions }).to include(14)
122
+ expect(Octopus.using(:russia) { get_all_versions }).to include(14)
123
+ end
124
+ end
125
+
126
+ it 'should run the migrations on shards that are missing them' do
127
+ class SchemaMigration < ActiveRecord::Base; end
128
+
129
+ Octopus.using(:master) { SchemaMigration.create(:version => 14) }
130
+ Octopus.using(:canada) { SchemaMigration.create(:version => 14) }
131
+
132
+ OctopusHelper.migrating_to_version 14 do
133
+ expect(Octopus.using(:canada) { get_all_versions }).to include(14)
134
+ expect(Octopus.using(:brazil) { get_all_versions }).to include(14)
135
+ expect(Octopus.using(:russia) { get_all_versions }).to include(14)
136
+ end
137
+ end
138
+
139
+ describe 'when using a default_migration_group' do
140
+ it 'should run migrations on all shards in the default_migration_group' do
141
+ OctopusHelper.using_environment :octopus_with_default_migration_group do
142
+ OctopusHelper.migrating_to_version 15 do
143
+ expect(Octopus.using(:master) { get_all_versions }).not_to include(15)
144
+ expect(Octopus.using(:canada) { get_all_versions }).to include(15)
145
+ expect(Octopus.using(:brazil) { get_all_versions }).to include(15)
146
+ expect(Octopus.using(:russia) { get_all_versions }).to include(15)
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end