data_fabric 1.0.0

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 (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