data_fabric 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/CHANGELOG +1 -0
  2. data/Manifest +79 -0
  3. data/README.rdoc +108 -0
  4. data/Rakefile +69 -0
  5. data/TESTING.rdoc +34 -0
  6. data/TODO +1 -0
  7. data/data_fabric.gemspec +166 -0
  8. data/example/Rakefile +58 -0
  9. data/example/app/controllers/accounts_controller.rb +22 -0
  10. data/example/app/controllers/application.rb +39 -0
  11. data/example/app/controllers/figments_controller.rb +8 -0
  12. data/example/app/helpers/accounts_helper.rb +2 -0
  13. data/example/app/helpers/application_helper.rb +3 -0
  14. data/example/app/helpers/figments_helper.rb +2 -0
  15. data/example/app/models/account.rb +3 -0
  16. data/example/app/models/figment.rb +4 -0
  17. data/example/app/views/accounts/index.html.erb +47 -0
  18. data/example/app/views/layouts/application.html.erb +8 -0
  19. data/example/config/boot.rb +109 -0
  20. data/example/config/database.yml +21 -0
  21. data/example/config/environment.rb +67 -0
  22. data/example/config/environments/development.rb +17 -0
  23. data/example/config/environments/production.rb +22 -0
  24. data/example/config/environments/test.rb +22 -0
  25. data/example/config/initializers/inflections.rb +10 -0
  26. data/example/config/initializers/mime_types.rb +5 -0
  27. data/example/config/initializers/new_rails_defaults.rb +15 -0
  28. data/example/config/routes.rb +45 -0
  29. data/example/db/development.sqlite3 +0 -0
  30. data/example/db/migrate/20080702154628_create_accounts.rb +14 -0
  31. data/example/db/migrate/20080702154820_create_figments.rb +14 -0
  32. data/example/db/s0_development.sqlite3 +0 -0
  33. data/example/db/s0_test.sqlite3 +0 -0
  34. data/example/db/s1_development.sqlite3 +0 -0
  35. data/example/db/s1_test.sqlite3 +0 -0
  36. data/example/db/schema.rb +28 -0
  37. data/example/db/test.sqlite3 +0 -0
  38. data/example/public/404.html +30 -0
  39. data/example/public/422.html +30 -0
  40. data/example/public/500.html +30 -0
  41. data/example/public/dispatch.cgi +10 -0
  42. data/example/public/dispatch.fcgi +24 -0
  43. data/example/public/dispatch.rb +10 -0
  44. data/example/public/favicon.ico +0 -0
  45. data/example/public/images/rails.png +0 -0
  46. data/example/public/javascripts/application.js +2 -0
  47. data/example/public/javascripts/controls.js +963 -0
  48. data/example/public/javascripts/dragdrop.js +972 -0
  49. data/example/public/javascripts/effects.js +1120 -0
  50. data/example/public/javascripts/prototype.js +4225 -0
  51. data/example/public/robots.txt +5 -0
  52. data/example/script/about +3 -0
  53. data/example/script/console +3 -0
  54. data/example/script/dbconsole +3 -0
  55. data/example/script/destroy +3 -0
  56. data/example/script/generate +3 -0
  57. data/example/script/performance/benchmarker +3 -0
  58. data/example/script/performance/profiler +3 -0
  59. data/example/script/performance/request +3 -0
  60. data/example/script/plugin +3 -0
  61. data/example/script/process/inspector +3 -0
  62. data/example/script/process/reaper +3 -0
  63. data/example/script/process/spawner +3 -0
  64. data/example/script/runner +3 -0
  65. data/example/script/server +3 -0
  66. data/example/test/fixtures/accounts.yml +7 -0
  67. data/example/test/functional/accounts_controller_test.rb +12 -0
  68. data/example/test/integration/account_figments_test.rb +95 -0
  69. data/example/test/test_helper.rb +41 -0
  70. data/example/vendor/plugins/data_fabric/init.rb +1 -0
  71. data/example/vendor/plugins/data_fabric/lib/data_fabric.rb +231 -0
  72. data/init.rb +1 -0
  73. data/lib/data_fabric/version.rb +5 -0
  74. data/lib/data_fabric.rb +231 -0
  75. data/test/connection_test.rb +103 -0
  76. data/test/database.yml +27 -0
  77. data/test/database_test.rb +39 -0
  78. data/test/shard_test.rb +24 -0
  79. data/test/test_helper.rb +17 -0
  80. data/test/thread_test.rb +91 -0
  81. metadata +164 -0
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ http://github.com/fiveruns/data_fabric/commits/master
data/Manifest ADDED
@@ -0,0 +1,79 @@
1
+ CHANGELOG
2
+ example/app/controllers/accounts_controller.rb
3
+ example/app/controllers/application.rb
4
+ example/app/controllers/figments_controller.rb
5
+ example/app/helpers/accounts_helper.rb
6
+ example/app/helpers/application_helper.rb
7
+ example/app/helpers/figments_helper.rb
8
+ example/app/models/account.rb
9
+ example/app/models/figment.rb
10
+ example/app/views/accounts/index.html.erb
11
+ example/app/views/layouts/application.html.erb
12
+ example/config/boot.rb
13
+ example/config/database.yml
14
+ example/config/environment.rb
15
+ example/config/environments/development.rb
16
+ example/config/environments/production.rb
17
+ example/config/environments/test.rb
18
+ example/config/initializers/inflections.rb
19
+ example/config/initializers/mime_types.rb
20
+ example/config/initializers/new_rails_defaults.rb
21
+ example/config/routes.rb
22
+ example/db/development.sqlite3
23
+ example/db/migrate/20080702154628_create_accounts.rb
24
+ example/db/migrate/20080702154820_create_figments.rb
25
+ example/db/s0_development.sqlite3
26
+ example/db/s0_test.sqlite3
27
+ example/db/s1_development.sqlite3
28
+ example/db/s1_test.sqlite3
29
+ example/db/schema.rb
30
+ example/db/test.sqlite3
31
+ example/public/404.html
32
+ example/public/422.html
33
+ example/public/500.html
34
+ example/public/dispatch.cgi
35
+ example/public/dispatch.fcgi
36
+ example/public/dispatch.rb
37
+ example/public/favicon.ico
38
+ example/public/images/rails.png
39
+ example/public/javascripts/application.js
40
+ example/public/javascripts/controls.js
41
+ example/public/javascripts/dragdrop.js
42
+ example/public/javascripts/effects.js
43
+ example/public/javascripts/prototype.js
44
+ example/public/robots.txt
45
+ example/Rakefile
46
+ example/script/about
47
+ example/script/console
48
+ example/script/dbconsole
49
+ example/script/destroy
50
+ example/script/generate
51
+ example/script/performance/benchmarker
52
+ example/script/performance/profiler
53
+ example/script/performance/request
54
+ example/script/plugin
55
+ example/script/process/inspector
56
+ example/script/process/reaper
57
+ example/script/process/spawner
58
+ example/script/runner
59
+ example/script/server
60
+ example/test/fixtures/accounts.yml
61
+ example/test/functional/accounts_controller_test.rb
62
+ example/test/integration/account_figments_test.rb
63
+ example/test/test_helper.rb
64
+ example/vendor/plugins/data_fabric/init.rb
65
+ example/vendor/plugins/data_fabric/lib/data_fabric.rb
66
+ init.rb
67
+ lib/data_fabric/version.rb
68
+ lib/data_fabric.rb
69
+ Rakefile
70
+ README.rdoc
71
+ test/connection_test.rb
72
+ test/database.yml
73
+ test/database_test.rb
74
+ test/shard_test.rb
75
+ test/test_helper.rb
76
+ test/thread_test.rb
77
+ TESTING.rdoc
78
+ TODO
79
+ Manifest
data/README.rdoc ADDED
@@ -0,0 +1,108 @@
1
+ = data_fabric
2
+
3
+ DataFabric provides flexible database connection switching for ActiveRecord.
4
+
5
+ We needed two features to scale our mysql database: application-level sharding and
6
+ master/slave replication. Sharding is the process of splitting a dataset across many
7
+ independent databases. This often happens based on geographical region (e.g.
8
+ craigslist) or category (e.g. ebay). Replication provides a near-real-time copy
9
+ of a database which can be used for fault tolerance and to reduce load on the master
10
+ node. Combined, you get a scalable database solution which does not require huge
11
+ hardware to scale to huge volumes. Or: DPAYEIOB - don't put all your eggs in one
12
+ basket. :-)
13
+
14
+ == Installation
15
+
16
+ gem install data_fabric
17
+
18
+ == How does it work?
19
+
20
+ You describe the topology for your database infrastructure in your model(s).
21
+ Different models can use different topologies.
22
+
23
+ class MyHugeVolumeOfDataModel < ActiveRecord::Base
24
+ connection_topology :replicated => true, :shard_by => :city
25
+ end
26
+
27
+ There are four supported modes of operation, depending on the options given to the
28
+ connection_topology method. The plugin will look for connections in your
29
+ config/database.yml with the following convention:
30
+
31
+ No connection topology:
32
+ #{environment} - this is the default, as with ActiveRecord, e.g. "production"
33
+
34
+ connection_topology :replicated => true
35
+ #{environment}_#{role} - no sharding, just replication, where role is "master" or "slave", e.g. "production_master"
36
+
37
+ connection_topology :shard_by => :city
38
+ #{group}_#{shard}_#{environment} - sharding, no replication, e.g. "city_austin_production"
39
+
40
+ connection_topology :replicated => true, :shard_by => :city
41
+ #{group}_#{shard}_#{environment}_#{role} - sharding with replication, e.g. "city_austin_production_master"
42
+
43
+
44
+ When marked as replicated, all write and transactional operations for the model
45
+ go to the master, whereas read operations go to the slave.
46
+
47
+ Since sharding is an application-level concern, your application must set the shard
48
+ to use based on the current request or environment. The current shard
49
+ is set on a thread local variable. For example, you can set the shard in an
50
+ ActionController around_filter based on the user as follows:
51
+
52
+ class ApplicationController < ActionController::Base
53
+ around_filter :select_shard
54
+
55
+ private
56
+ def select_shard(&block)
57
+ DataFabric.activate_shard(:city => @current_user.city, &block)
58
+ end
59
+ end
60
+
61
+
62
+ == Warnings
63
+
64
+ * Sharded models should never be placed in the session store or you will get "Shard not set" errors when the session is persisted.
65
+ * ActiveRecord's allow_concurrency = true is NOT supported in this version of data_fabric.
66
+
67
+ == Testing and Bug Reports
68
+
69
+ If you think you've found a problem with data_fabric, please use the example application to reproduce the bug and send me the diff. The example application is a stock Rails 2.1 application which uses data_fabric in the expected fashion.
70
+
71
+
72
+ == Thanks to...
73
+
74
+ Rick Olsen of Rails Core:: for the Masochism plugin, which showed me how to bend AR's connection handling to my will
75
+ Bradley Taylor of RailsMachine:: for the advice to shard while at acts_as_conference
76
+ FiveRuns:: for paying me to develop this code and allowing its release
77
+
78
+
79
+ == Author
80
+
81
+ Mike Perham <mperham@gmail.com>
82
+ http://mikeperham.com
83
+
84
+
85
+ == LICENSE:
86
+
87
+ (The FiveRuns License)
88
+
89
+ Copyright (c) 2008 FiveRuns Corporation
90
+
91
+ Permission is hereby granted, free of charge, to any person obtaining
92
+ a copy of this software and associated documentation files (the
93
+ 'Software'), to deal in the Software without restriction, including
94
+ without limitation the rights to use, copy, modify, merge, publish,
95
+ distribute, sublicense, and/or sell copies of the Software, and to
96
+ permit persons to whom the Software is furnished to do so, subject to
97
+ the following conditions:
98
+
99
+ The above copyright notice and this permission notice shall be
100
+ included in all copies or substantial portions of the Software.
101
+
102
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
103
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
104
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
105
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
106
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
107
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
108
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,69 @@
1
+ require 'rubygems'
2
+ require 'echoe'
3
+
4
+ require File.dirname(__FILE__) << "/lib/data_fabric/version"
5
+
6
+ Echoe.new 'data_fabric' do |p|
7
+ p.version = DataFabric::Version::STRING
8
+ p.author = "Mike Perham"
9
+ p.email = 'mperham@gmail.com'
10
+ p.project = 'fiveruns'
11
+ p.summary = 'Sharding and replication support for ActiveRecord 2.x'
12
+ p.url = "http://github.com/fiveruns/data_fabric"
13
+ p.dependencies = ['activerecord >=2.0.2']
14
+ p.include_rakefile = true
15
+ end
16
+
17
+ require 'rake/testtask'
18
+
19
+ RAILS_ROOT=File.dirname(__FILE__)
20
+
21
+ Rake::TestTask.new do |t|
22
+ t.test_files = FileList['test/*_test.rb']
23
+ t.verbose = true
24
+ end
25
+
26
+ task :pretest do
27
+ setup(false)
28
+ end
29
+
30
+ task :create_db do
31
+ setup(true)
32
+ end
33
+
34
+ task :changelog do
35
+ `git log | grep -v git-svn-id > History.txt`
36
+ end
37
+
38
+ def setup_connection
39
+ require 'active_record'
40
+ ENV['RAILS_ENV'] = 'test'
41
+
42
+ ActiveRecord::Base.configurations = { 'test' => { :adapter => 'mysql', :host => 'localhost', :database => 'mysql' } }
43
+ ActiveRecord::Base.establish_connection 'test'
44
+ end
45
+
46
+ def using_connection(&block)
47
+ ActiveRecord::Base.connection.instance_eval(&block)
48
+ end
49
+
50
+ def setup(create = false)
51
+ setup_connection
52
+
53
+ databases = %w( vr_austin_master vr_austin_slave vr_dallas_master vr_dallas_slave )
54
+ databases.each do |db|
55
+ using_connection do
56
+ if create
57
+ execute "drop database if exists #{db}"
58
+ execute "create database #{db}"
59
+ end
60
+ execute "use #{db}"
61
+ execute "drop table if exists the_whole_burritos"
62
+ execute "drop table if exists enchiladas"
63
+ execute "create table enchiladas (id integer not null auto_increment, name varchar(30) not null, primary key(id))"
64
+ execute "insert into enchiladas (id, name) values (1, '#{db}')"
65
+ execute "create table the_whole_burritos (id integer not null auto_increment, name varchar(30) not null, primary key(id))"
66
+ execute "insert into the_whole_burritos (id, name) values (1, '#{db}')"
67
+ end
68
+ end
69
+ end
data/TESTING.rdoc ADDED
@@ -0,0 +1,34 @@
1
+ Because of what it does, data_fabric is difficult to test easily.
2
+
3
+ There are two layers of tests: unit tests and integration tests.
4
+
5
+
6
+ == Running the Unit Tests
7
+
8
+ The unit tests test both with and without an actual database. test/database_test.rb
9
+ tests against a MySQL database. The other unit tests mock AR so no actual database is
10
+ required. You must customize test/database.yml to point to your MySQL database.
11
+ "rake pretest" will set up MySQL to run the tests but you will need to customize
12
+ the connection settings in the Rakefile pretest task.
13
+
14
+
15
+ == Running the Integration Tests
16
+
17
+ data_fabric ships with an example application which shows an actual Rails application
18
+ using data_fabric. You can customize config/database.yml but by default it uses a local
19
+ Sqlite3 database so there should be no customization necessary.
20
+
21
+ Run the Rake task to prepare the application for testing. This will copy the latest data_fabric code
22
+ to vendor/plugins, delete existing databases and migrate all the databases from scratch. You should
23
+ then be able to run the example application's tests.
24
+
25
+ cd example
26
+ rake app:prepare
27
+ rake test
28
+
29
+
30
+ == Submitting Bugs
31
+
32
+ If you think you've found a problem with data_fabric, please write a unit or integration test
33
+ which reproduces the problem. This should make tracking down and fixing the bug relatively
34
+ easy and provides a regression test for future releases.
data/TODO ADDED
@@ -0,0 +1 @@
1
+ Process or Documentation for how to migrate existing data to shards
@@ -0,0 +1,166 @@
1
+
2
+ # Gem::Specification for Data_fabric-1.0.0
3
+ # Originally generated by Echoe
4
+
5
+ --- !ruby/object:Gem::Specification
6
+ name: data_fabric
7
+ version: !ruby/object:Gem::Version
8
+ version: 1.0.0
9
+ platform: ruby
10
+ authors:
11
+ - Mike Perham
12
+ autorequire:
13
+ bindir: bin
14
+
15
+ date: 2008-07-08 00:00:00 -05:00
16
+ default_executable:
17
+ dependencies:
18
+ - !ruby/object:Gem::Dependency
19
+ name: activerecord
20
+ type: :runtime
21
+ version_requirement:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.2
27
+ version:
28
+ - !ruby/object:Gem::Dependency
29
+ name: echoe
30
+ type: :development
31
+ version_requirement:
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: "0"
37
+ version:
38
+ description: Sharding and replication support for ActiveRecord 2.x
39
+ email: mperham@gmail.com
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files:
45
+ - CHANGELOG
46
+ - lib/data_fabric/version.rb
47
+ - lib/data_fabric.rb
48
+ - README.rdoc
49
+ - TODO
50
+ files:
51
+ - CHANGELOG
52
+ - example/app/controllers/accounts_controller.rb
53
+ - example/app/controllers/application.rb
54
+ - example/app/controllers/figments_controller.rb
55
+ - example/app/helpers/accounts_helper.rb
56
+ - example/app/helpers/application_helper.rb
57
+ - example/app/helpers/figments_helper.rb
58
+ - example/app/models/account.rb
59
+ - example/app/models/figment.rb
60
+ - example/app/views/accounts/index.html.erb
61
+ - example/app/views/layouts/application.html.erb
62
+ - example/config/boot.rb
63
+ - example/config/database.yml
64
+ - example/config/environment.rb
65
+ - example/config/environments/development.rb
66
+ - example/config/environments/production.rb
67
+ - example/config/environments/test.rb
68
+ - example/config/initializers/inflections.rb
69
+ - example/config/initializers/mime_types.rb
70
+ - example/config/initializers/new_rails_defaults.rb
71
+ - example/config/routes.rb
72
+ - example/db/development.sqlite3
73
+ - example/db/migrate/20080702154628_create_accounts.rb
74
+ - example/db/migrate/20080702154820_create_figments.rb
75
+ - example/db/s0_development.sqlite3
76
+ - example/db/s0_test.sqlite3
77
+ - example/db/s1_development.sqlite3
78
+ - example/db/s1_test.sqlite3
79
+ - example/db/schema.rb
80
+ - example/db/test.sqlite3
81
+ - example/public/404.html
82
+ - example/public/422.html
83
+ - example/public/500.html
84
+ - example/public/dispatch.cgi
85
+ - example/public/dispatch.fcgi
86
+ - example/public/dispatch.rb
87
+ - example/public/favicon.ico
88
+ - example/public/images/rails.png
89
+ - example/public/javascripts/application.js
90
+ - example/public/javascripts/controls.js
91
+ - example/public/javascripts/dragdrop.js
92
+ - example/public/javascripts/effects.js
93
+ - example/public/javascripts/prototype.js
94
+ - example/public/robots.txt
95
+ - example/Rakefile
96
+ - example/script/about
97
+ - example/script/console
98
+ - example/script/dbconsole
99
+ - example/script/destroy
100
+ - example/script/generate
101
+ - example/script/performance/benchmarker
102
+ - example/script/performance/profiler
103
+ - example/script/performance/request
104
+ - example/script/plugin
105
+ - example/script/process/inspector
106
+ - example/script/process/reaper
107
+ - example/script/process/spawner
108
+ - example/script/runner
109
+ - example/script/server
110
+ - example/test/fixtures/accounts.yml
111
+ - example/test/functional/accounts_controller_test.rb
112
+ - example/test/integration/account_figments_test.rb
113
+ - example/test/test_helper.rb
114
+ - example/vendor/plugins/data_fabric/init.rb
115
+ - example/vendor/plugins/data_fabric/lib/data_fabric.rb
116
+ - init.rb
117
+ - lib/data_fabric/version.rb
118
+ - lib/data_fabric.rb
119
+ - Rakefile
120
+ - README.rdoc
121
+ - test/connection_test.rb
122
+ - test/database.yml
123
+ - test/database_test.rb
124
+ - test/shard_test.rb
125
+ - test/test_helper.rb
126
+ - test/thread_test.rb
127
+ - TESTING.rdoc
128
+ - TODO
129
+ - Manifest
130
+ - data_fabric.gemspec
131
+ has_rdoc: true
132
+ homepage: http://github.com/fiveruns/data_fabric
133
+ post_install_message:
134
+ rdoc_options:
135
+ - --line-numbers
136
+ - --inline-source
137
+ - --title
138
+ - Data_fabric
139
+ - --main
140
+ - README.rdoc
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: "0"
148
+ version:
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "="
152
+ - !ruby/object:Gem::Version
153
+ version: "1.2"
154
+ version:
155
+ requirements: []
156
+
157
+ rubyforge_project: fiveruns
158
+ rubygems_version: 1.2.0
159
+ specification_version: 2
160
+ summary: Sharding and replication support for ActiveRecord 2.x
161
+ test_files:
162
+ - test/connection_test.rb
163
+ - test/database_test.rb
164
+ - test/shard_test.rb
165
+ - test/test_helper.rb
166
+ - test/thread_test.rb