global_uid 1.4.0 → 1.4.1

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.
@@ -48,6 +48,10 @@ module GlobalUid
48
48
  @global_uid_disabled = true
49
49
  end
50
50
 
51
+ def enable_global_uid
52
+ @global_uid_disabled = false
53
+ end
54
+
51
55
  def global_uid_table
52
56
  GlobalUid::Base.id_table_from_name(self.table_name)
53
57
  end
@@ -61,7 +61,7 @@ module GlobalUid
61
61
  GlobalUidTimer = Timeout
62
62
  end
63
63
 
64
- def self.new_connection(name, connection_timeout, offset, increment_by, use_server_variables)
64
+ def self.new_connection(name, connection_timeout, offset, increment_by)
65
65
  raise "No id server '#{name}' configured in database.yml" unless ActiveRecord::Base.configurations.has_key?(name)
66
66
  config = ActiveRecord::Base.configurations[name]
67
67
  c = config.symbolize_keys
@@ -81,14 +81,6 @@ module GlobalUid
81
81
  return nil
82
82
  end
83
83
 
84
- # Please note that this is unreliable -- if you lose your CX to the server
85
- # and auto-reconnect, you will be utterly hosed. Much better to dedicate a server
86
- # or two to the cause, and set their auto_increment_increment globally.
87
- if use_server_variables
88
- con.execute("set @@auto_increment_increment = #{increment_by}")
89
- con.execute("set @@auto_increment_offset = #{offset}")
90
- end
91
-
92
84
  con
93
85
  end
94
86
 
@@ -133,7 +125,7 @@ module GlobalUid
133
125
  if info[:new?] || ( info[:retry_at] && Time.now > info[:retry_at] )
134
126
  info[:new?] = false
135
127
 
136
- connection = new_connection(info[:name], connection_timeout, info[:offset], increment_by, options[:use_server_variables])
128
+ connection = new_connection(info[:name], connection_timeout, info[:offset], increment_by)
137
129
  info[:cx] = connection
138
130
  info[:retry_at] = Time.now + options[:connection_retry] if connection.nil?
139
131
  end
@@ -0,0 +1,29 @@
1
+ # This module is good for testing and development, not so much for production.
2
+ # Please note that this is unreliable -- if you lose your CX to the server
3
+ # and auto-reconnect, you will be utterly hosed. Much better to dedicate a server
4
+ # or two to the cause, and set their auto_increment_increment globally.
5
+ #
6
+ # You can include this module in tests like this:
7
+ # GlobalUid::Base.extend(GlobalUid::ServerVariables)
8
+ #
9
+ module GlobalUid
10
+ module ServerVariables
11
+
12
+ def self.extended(base)
13
+ base.singleton_class.send(:alias_method, :new_connection_without_server_variables, :new_connection)
14
+ base.singleton_class.send(:alias_method, :new_connection, :new_connection_with_server_variables)
15
+ end
16
+
17
+ def new_connection_with_server_variables(name, connection_timeout, offset, increment_by)
18
+ con = new_connection_without_server_variables(name, connection_timeout, offset, increment_by)
19
+
20
+ if con
21
+ con.execute("set @@auto_increment_increment = #{increment_by}")
22
+ con.execute("set @@auto_increment_offset = #{offset}")
23
+ end
24
+
25
+ con
26
+ end
27
+
28
+ end
29
+ end
data/lib/global_uid.rb CHANGED
@@ -3,11 +3,13 @@ require "global_uid/active_record_extension"
3
3
  require "global_uid/migration_extension"
4
4
 
5
5
  module GlobalUid
6
- VERSION = "1.3.1"
6
+ VERSION = "1.4.1"
7
7
 
8
8
  class NoServersAvailableException < Exception ; end
9
9
  class ConnectionTimeoutException < Exception ; end
10
10
  class TimeoutException < Exception ; end
11
+
12
+ autoload :ServerVariables, "global_uid/server_variables"
11
13
  end
12
14
 
13
15
  ActiveRecord::Base.send(:include, GlobalUid::ActiveRecordExtension)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: global_uid
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.4.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-01 00:00:00.000000000 Z
12
+ date: 2014-06-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -139,35 +139,38 @@ dependencies:
139
139
  - - ! '>='
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: test-unit
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
142
158
  description: GUIDs for sharded models
143
159
  email: ben@zendesk.com
144
160
  executables: []
145
161
  extensions: []
146
- extra_rdoc_files:
147
- - README.md
162
+ extra_rdoc_files: []
148
163
  files:
149
- - Appraisals
150
- - Gemfile
151
- - README.md
152
- - Rakefile
153
- - gemfiles/rails2.gemfile
154
- - gemfiles/rails2.gemfile.lock
155
- - gemfiles/rails2mysql2.gemfile.lock
156
- - gemfiles/rails3.gemfile
157
- - gemfiles/rails3.gemfile.lock
158
- - global_uid.gemspec
159
164
  - lib/global_uid.rb
160
165
  - lib/global_uid/active_record_extension.rb
161
166
  - lib/global_uid/base.rb
162
167
  - lib/global_uid/migration_extension.rb
163
- - test/config/database.yml.example
164
- - test/global_uid_test.rb
165
- - test/test_helper.rb
166
- homepage: http://github.com/zendesk/global_uid
167
- licenses: []
168
+ - lib/global_uid/server_variables.rb
169
+ homepage: https://github.com/zendesk/global_uid
170
+ licenses:
171
+ - MIT
168
172
  post_install_message:
169
- rdoc_options:
170
- - --charset=UTF-8
173
+ rdoc_options: []
171
174
  require_paths:
172
175
  - lib
173
176
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -181,13 +184,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
184
  requirements:
182
185
  - - ! '>='
183
186
  - !ruby/object:Gem::Version
184
- version: 1.3.6
187
+ version: '0'
185
188
  requirements: []
186
- rubyforge_project: global_uid
187
- rubygems_version: 1.8.24
189
+ rubyforge_project:
190
+ rubygems_version: 1.8.23.2
188
191
  signing_key:
189
- specification_version: 2
192
+ specification_version: 3
190
193
  summary: GUID
191
- test_files:
192
- - test/global_uid_test.rb
193
- - test/test_helper.rb
194
+ test_files: []
data/Appraisals DELETED
@@ -1,12 +0,0 @@
1
- appraise "rails2" do
2
- gem "activerecord", "2.3.14"
3
- end
4
-
5
- appraise "rails2mysql2" do
6
- gem "activerecord", "2.3.14"
7
- gem "mysql2", :git => "git://github.com/osheroff/mysql2.git", :ref => "a1ab7ba"
8
- end
9
-
10
- appraise "rails3" do
11
- gem "activerecord", "3.2.2"
12
- end
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem "ruby-debug", :platform => "mri_18", :group => "test"
6
- gem "debugger", :platform => "mri_19", :require => "ruby-debug", :group => "test"
data/README.md DELETED
@@ -1,130 +0,0 @@
1
- # Global UID Plugin
2
-
3
- ## Summary
4
-
5
- This plugin does a lot of the heavy lifting needed to have an external MySQL based global id generator as described in this article from Flickr
6
-
7
- (http://code.flickr.com/blog/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/)
8
-
9
- There are three parts to it: configuration, migration and object creation
10
-
11
- ### Interactions with other databases
12
-
13
- This plugin shouldn't fail with Databases other than MySQL but neither will it do anything either. There's theoretically nothing that should stop it from being *ported* to other DBs, we just don't need to.
14
-
15
- ## Installation
16
-
17
- Shove this in your Gemfile and smoke it
18
-
19
- gem "global_uid", :git => "git://github.com/zendesk/global_uid.git"
20
-
21
- ### Configuration
22
-
23
- First configure some databases in database.yml in the normal way.
24
-
25
- id_server_1:
26
- adapter: mysql
27
- host: id_server_db1.prod
28
- port: 3306
29
-
30
- id_server_2:
31
- adapter: mysql
32
- host: id_server_db2.prod
33
- port: 3306
34
-
35
- Then setup these servers, and other defaults in your environment.rb:
36
-
37
- GlobalUid.default_options = {
38
- :id_servers => [ 'id_server_1', 'id_server_2' ],
39
- :increment_by => 3
40
- }
41
-
42
- Here's a complete list of the options you can use:
43
-
44
- Name Default
45
- :disabled false
46
- Disable GlobalUid entirely
47
-
48
- :dry_run false
49
- Setting this parameter causes the REPLACE INTO statements to run, but the id picked up will not be used.
50
-
51
- :connection_timeout 3 seconds
52
- Timeout for connecting to a global UID server
53
-
54
- :query_timeout 10 seconds
55
- Timeout for retrieving a global UID from a server before we move on to the next server
56
-
57
- :connection_retry 10.minutes
58
- After failing to connect or query a UID server, how long before we retry
59
-
60
- :use_server_variables false
61
- If set, this gem will call "set @@auto_increment_offset" in order to setup the global uid servers.
62
- good for test/development, not so much for production.
63
- :notifier A proc calling ActiveRecord::Base.logger
64
- This proc is called with two parameters upon UID server failure -- an exception and a message
65
-
66
- :increment_by 5
67
- Chooses the step size for the increment. This will define the maximum number of UID servers you can have.
68
-
69
- ### Testing
70
-
71
- mysqladmin -uroot create global_uid_test
72
- mysqladmin -uroot create global_uid_test_id_server_1
73
- mysqladmin -uroot create global_uid_test_id_server_2
74
-
75
- Copy test/config/database.yml.example to test/config/database.yml and make the modifications you need to point it to 2 local MySQL databases. Then +rake test+
76
-
77
- ### Migration
78
-
79
- Migrations will now add global_uid tables for you by default. They will also change
80
- your primary keys from signature "PRIMARY KEY AUTO_INCREMENT NOT NULL" to "PRIMARY KEY NOT NULL".
81
-
82
- If you'd like to disable this behavior, you can write:
83
-
84
- class CreateFoos < ActiveRecord::Migration
85
- def self.up
86
- create_table :foos, :use_global_uid => false do |t|
87
-
88
-
89
- ## Model-level stuff
90
-
91
- If you want GlobalUIDs created, you don't have to do anything except set up the GlobalUID tables
92
- with your migration. Everything will be taken care you. It's calm, and soothing like aloe.
93
- It's the Rails way.
94
-
95
-
96
- ### Disabling global uid per table
97
-
98
- class Foo < ActiveRecord::Base
99
- disable_global_uid
100
- end
101
-
102
-
103
- ## Taking matters into your own hands:
104
-
105
-
106
- class Foo < ActiveRecord::Base
107
- disable_global_uid
108
-
109
- def before_create
110
- self.id = generate_uid()
111
- # other stuff
112
- ....
113
- end
114
-
115
- end
116
-
117
- If you're using a non standard uid table then pass that in.
118
-
119
- generate_uid(:uid_table => '<name>')
120
-
121
- ## Submitting Bug reports, patches or improvements
122
-
123
- I welcome your feedback, bug reports, patches and improvements. Please e-mail these
124
- to
125
- simon at zendesk.com
126
-
127
-
128
- with [mysqlbigint global uid] in the subject line. I'll get back to you as soon as I can.
129
-
130
- Copyright (c) 2010 Zendesk, released under the MIT license
data/Rakefile DELETED
@@ -1,151 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'date'
4
- require 'appraisal'
5
-
6
- #############################################################################
7
- #
8
- # Helper functions
9
- #
10
- #############################################################################
11
-
12
- def name
13
- @name ||= Dir['*.gemspec'].first.split('.').first
14
- end
15
-
16
- def version
17
- line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
18
- line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
19
- end
20
-
21
- def date
22
- Date.today.to_s
23
- end
24
-
25
- def rubyforge_project
26
- name
27
- end
28
-
29
- def gemspec_file
30
- "#{name}.gemspec"
31
- end
32
-
33
- def gem_file
34
- "#{name}-#{version}.gem"
35
- end
36
-
37
- def replace_header(head, header_name)
38
- head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
39
- end
40
-
41
- #############################################################################
42
- #
43
- # Standard tasks
44
- #
45
- #############################################################################
46
-
47
- task :default => :test
48
-
49
- require 'rake/testtask'
50
- Rake::TestTask.new(:test) do |test|
51
- test.libs << 'lib' << 'test'
52
- test.pattern = 'test/**/*_test.rb'
53
- test.verbose = true
54
- end
55
-
56
- desc "Generate RCov test coverage and open in your browser"
57
- task :coverage do
58
- require 'rcov'
59
- sh "rm -fr coverage"
60
- sh "rcov test/test_*.rb"
61
- sh "open coverage/index.html"
62
- end
63
-
64
- require 'rake/rdoctask'
65
- Rake::RDocTask.new do |rdoc|
66
- rdoc.rdoc_dir = 'rdoc'
67
- rdoc.title = "#{name} #{version}"
68
- rdoc.rdoc_files.include('README*')
69
- rdoc.rdoc_files.include('lib/**/*.rb')
70
- end
71
-
72
- desc "Open an irb session preloaded with this library"
73
- task :console do
74
- sh "irb -rubygems -r ./lib/#{name}.rb"
75
- end
76
-
77
- #############################################################################
78
- #
79
- # Custom tasks (add your own tasks here)
80
- #
81
- #############################################################################
82
-
83
-
84
-
85
- #############################################################################
86
- #
87
- # Packaging tasks
88
- #
89
- #############################################################################
90
-
91
- desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
92
- task :release => :build do
93
- unless `git branch` =~ /^\* master$/
94
- puts "You must be on the master branch to release!"
95
- exit!
96
- end
97
- sh "git commit --allow-empty -a -m 'Release #{version}'"
98
- sh "git tag v#{version}"
99
- sh "git push origin master"
100
- sh "git push origin v#{version}"
101
- sh "gem push pkg/#{name}-#{version}.gem"
102
- end
103
-
104
- desc "Build #{gem_file} into the pkg directory"
105
- task :build => :gemspec do
106
- sh "mkdir -p pkg"
107
- sh "gem build #{gemspec_file}"
108
- sh "mv #{gem_file} pkg"
109
- end
110
-
111
- desc "Generate #{gemspec_file}"
112
- task :gemspec => :validate do
113
- # read spec file and split out manifest section
114
- spec = File.read(gemspec_file)
115
- head, manifest, tail = spec.split(" # = MANIFEST =\n")
116
-
117
- # replace name version and date
118
- replace_header(head, :name)
119
- replace_header(head, :version)
120
- replace_header(head, :date)
121
- #comment this out if your rubyforge_project has a different name
122
- replace_header(head, :rubyforge_project)
123
-
124
- # determine file list from git ls-files
125
- files = `git ls-files`.
126
- split("\n").
127
- sort.
128
- reject { |file| file =~ /^\./ }.
129
- reject { |file| file =~ /^(rdoc|pkg)/ }.
130
- map { |file| " #{file}" }.
131
- join("\n")
132
-
133
- # piece file back together and write
134
- manifest = " s.files = %w[\n#{files}\n ]\n"
135
- spec = [head, manifest, tail].join(" # = MANIFEST =\n")
136
- File.open(gemspec_file, 'w') { |io| io.write(spec) }
137
- puts "Updated #{gemspec_file}"
138
- end
139
-
140
- desc "Validate #{gemspec_file}"
141
- task :validate do
142
- libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
143
- unless libfiles.empty?
144
- puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
145
- exit!
146
- end
147
- unless Dir['VERSION*'].empty?
148
- puts "A `VERSION` file at root level violates Gem best practices."
149
- exit!
150
- end
151
- end
@@ -1,9 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "http://rubygems.org"
4
-
5
- gem "ruby-debug", :platform=>"mri_18", :group=>"test"
6
- gem "debugger", :platform=>"mri_19", :require=>"ruby-debug", :group=>"test"
7
- gem "activerecord", "2.3.14"
8
-
9
- gemspec :path=>"../"
@@ -1,53 +0,0 @@
1
- PATH
2
- remote: /Users/ben/src/global_uid
3
- specs:
4
- global_uid (1.2.6)
5
- activerecord
6
- activesupport
7
-
8
- GEM
9
- remote: http://rubygems.org/
10
- specs:
11
- activerecord (2.3.14)
12
- activesupport (= 2.3.14)
13
- activesupport (2.3.14)
14
- appraisal (0.4.0)
15
- bundler
16
- rake
17
- columnize (0.3.5)
18
- debugger (1.1.1)
19
- columnize (>= 0.3.1)
20
- debugger-linecache (~> 1.1)
21
- debugger-ruby_core_source (~> 1.1)
22
- debugger-linecache (1.1.1)
23
- debugger-ruby_core_source (>= 1.1.1)
24
- debugger-ruby_core_source (1.1.1)
25
- linecache (0.46)
26
- rbx-require-relative (> 0.0.4)
27
- metaclass (0.0.1)
28
- mocha (0.10.0)
29
- metaclass (~> 0.0.1)
30
- mysql (2.8.1)
31
- rake (0.9.2.2)
32
- rbx-require-relative (0.0.5)
33
- ruby-debug (0.10.4)
34
- columnize (>= 0.1)
35
- ruby-debug-base (~> 0.10.4.0)
36
- ruby-debug-base (0.10.4)
37
- linecache (>= 0.3)
38
- shoulda (2.11.3)
39
-
40
- PLATFORMS
41
- ruby
42
-
43
- DEPENDENCIES
44
- activerecord (= 2.3.14)
45
- appraisal
46
- bundler
47
- debugger
48
- global_uid!
49
- mocha
50
- mysql (= 2.8.1)
51
- rake
52
- ruby-debug
53
- shoulda
@@ -1,65 +0,0 @@
1
- GIT
2
- remote: git://github.com/osheroff/mysql2.git
3
- revision: a1ab7bae6252746c68677ad7a0d362e385dcd446
4
- ref: a1ab7ba
5
- specs:
6
- mysql2 (0.2.18)
7
-
8
- PATH
9
- remote: /Users/ben/src/global_uid
10
- specs:
11
- global_uid (1.2.6)
12
- activerecord
13
- activesupport
14
-
15
- GEM
16
- remote: http://rubygems.org/
17
- specs:
18
- activerecord (2.3.14)
19
- activesupport (= 2.3.14)
20
- activesupport (2.3.14)
21
- appraisal (0.4.1)
22
- bundler
23
- rake
24
- columnize (0.3.6)
25
- debugger (1.1.1)
26
- columnize (>= 0.3.1)
27
- debugger-linecache (~> 1.1)
28
- debugger-ruby_core_source (~> 1.1)
29
- debugger-linecache (1.1.1)
30
- debugger-ruby_core_source (>= 1.1.1)
31
- debugger-ruby_core_source (1.1.1)
32
- linecache (0.46)
33
- rbx-require-relative (> 0.0.4)
34
- metaclass (0.0.1)
35
- mocha (0.10.5)
36
- metaclass (~> 0.0.1)
37
- mysql (2.8.1)
38
- rake (0.9.2.2)
39
- rbx-require-relative (0.0.9)
40
- ruby-debug (0.10.4)
41
- columnize (>= 0.1)
42
- ruby-debug-base (~> 0.10.4.0)
43
- ruby-debug-base (0.10.4)
44
- linecache (>= 0.3)
45
- shoulda (3.0.1)
46
- shoulda-context (~> 1.0.0)
47
- shoulda-matchers (~> 1.0.0)
48
- shoulda-context (1.0.0)
49
- shoulda-matchers (1.0.0)
50
-
51
- PLATFORMS
52
- ruby
53
-
54
- DEPENDENCIES
55
- activerecord (= 2.3.14)
56
- appraisal
57
- bundler
58
- debugger
59
- global_uid!
60
- mocha
61
- mysql (= 2.8.1)
62
- mysql2!
63
- rake
64
- ruby-debug
65
- shoulda
@@ -1,9 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "http://rubygems.org"
4
-
5
- gem "ruby-debug", :platform=>"mri_18", :group=>"test"
6
- gem "debugger", :platform=>"mri_19", :require=>"ruby-debug", :group=>"test"
7
- gem "activerecord", "3.2.2"
8
-
9
- gemspec :path=>"../"
@@ -1,66 +0,0 @@
1
- PATH
2
- remote: /Users/ben/src/global_uid
3
- specs:
4
- global_uid (1.2.6)
5
- activerecord
6
- activesupport
7
-
8
- GEM
9
- remote: http://rubygems.org/
10
- specs:
11
- activemodel (3.2.2)
12
- activesupport (= 3.2.2)
13
- builder (~> 3.0.0)
14
- activerecord (3.2.2)
15
- activemodel (= 3.2.2)
16
- activesupport (= 3.2.2)
17
- arel (~> 3.0.2)
18
- tzinfo (~> 0.3.29)
19
- activesupport (3.2.2)
20
- i18n (~> 0.6)
21
- multi_json (~> 1.0)
22
- appraisal (0.4.0)
23
- bundler
24
- rake
25
- arel (3.0.2)
26
- builder (3.0.0)
27
- columnize (0.3.5)
28
- debugger (1.1.1)
29
- columnize (>= 0.3.1)
30
- debugger-linecache (~> 1.1)
31
- debugger-ruby_core_source (~> 1.1)
32
- debugger-linecache (1.1.1)
33
- debugger-ruby_core_source (>= 1.1.1)
34
- debugger-ruby_core_source (1.1.1)
35
- i18n (0.6.0)
36
- linecache (0.46)
37
- rbx-require-relative (> 0.0.4)
38
- metaclass (0.0.1)
39
- mocha (0.10.0)
40
- metaclass (~> 0.0.1)
41
- multi_json (1.1.0)
42
- mysql (2.8.1)
43
- rake (0.9.2.2)
44
- rbx-require-relative (0.0.5)
45
- ruby-debug (0.10.4)
46
- columnize (>= 0.1)
47
- ruby-debug-base (~> 0.10.4.0)
48
- ruby-debug-base (0.10.4)
49
- linecache (>= 0.3)
50
- shoulda (2.11.3)
51
- tzinfo (0.3.32)
52
-
53
- PLATFORMS
54
- ruby
55
-
56
- DEPENDENCIES
57
- activerecord (= 3.2.2)
58
- appraisal
59
- bundler
60
- debugger
61
- global_uid!
62
- mocha
63
- mysql (= 2.8.1)
64
- rake
65
- ruby-debug
66
- shoulda
data/global_uid.gemspec DELETED
@@ -1,90 +0,0 @@
1
- ## This is the rakegem gemspec template. Make sure you read and understand
2
- ## all of the comments. Some sections require modification, and others can
3
- ## be deleted if you don't need them. Once you understand the contents of
4
- ## this file, feel free to delete any comments that begin with two hash marks.
5
- ## You can find comprehensive Gem::Specification documentation, at
6
- ## http://docs.rubygems.org/read/chapter/20
7
- Gem::Specification.new do |s|
8
- s.specification_version = 2 if s.respond_to? :specification_version=
9
- s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6") if s.respond_to? :required_rubygems_version=
10
- s.rubygems_version = '1.3.6'
11
-
12
- ## Leave these as is they will be modified for you by the rake gemspec task.
13
- ## If your rubyforge_project name is different, then edit it and comment out
14
- ## the sub! line in the Rakefile
15
- s.name = 'global_uid'
16
- s.version = '1.4.0'
17
- s.date = '2013-04-01'
18
- s.rubyforge_project = 'global_uid'
19
-
20
- ## Make sure your summary is short. The description may be as long
21
- ## as you like.
22
- s.summary = "GUID"
23
- s.description = "GUIDs for sharded models"
24
-
25
- ## List the primary authors. If there are a bunch of authors, it's probably
26
- ## better to set the email to an email list or something. If you don't have
27
- ## a custom homepage, consider using your GitHub URL or the like.
28
- s.authors = ["Ben Osheroff"]
29
- s.email = 'ben@zendesk.com'
30
- s.homepage = 'http://github.com/zendesk/global_uid'
31
-
32
- ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
33
- ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
34
- s.require_paths = %w[lib]
35
-
36
- ## This sections is only necessary if you have C extensions.
37
- ## s.require_paths << 'ext'
38
- ## s.extensions = %w[ext/extconf.rb]
39
-
40
- ## If your gem includes any executables, list them here.
41
- # s.executables = ["name"]
42
-
43
- ## Specify any RDoc options here. You'll want to add your README and
44
- ## LICENSE files to the extra_rdoc_files list.
45
- s.rdoc_options = ["--charset=UTF-8"]
46
- s.extra_rdoc_files = %w[README.md]
47
-
48
- ## List your runtime dependencies here. Runtime dependencies are those
49
- ## that are needed for an end user to actually USE your code.
50
- s.add_dependency('activerecord')
51
- s.add_dependency('activesupport')
52
-
53
- ## List your development dependencies here. Development dependencies are
54
- ## those that are only needed during development
55
- s.add_development_dependency('mysql', '2.8.1')
56
- s.add_development_dependency("appraisal")
57
- s.add_development_dependency('rake')
58
- s.add_development_dependency('bundler')
59
- s.add_development_dependency('shoulda')
60
- s.add_development_dependency('mocha')
61
-
62
- ## Leave this section as-is. It will be automatically generated from the
63
- ## contents of your Git repository via the gemspec task. DO NOT REMOVE
64
- ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
65
- # = MANIFEST =
66
- s.files = %w[
67
- Appraisals
68
- Gemfile
69
- README.md
70
- Rakefile
71
- gemfiles/rails2.gemfile
72
- gemfiles/rails2.gemfile.lock
73
- gemfiles/rails2mysql2.gemfile.lock
74
- gemfiles/rails3.gemfile
75
- gemfiles/rails3.gemfile.lock
76
- global_uid.gemspec
77
- lib/global_uid.rb
78
- lib/global_uid/active_record_extension.rb
79
- lib/global_uid/base.rb
80
- lib/global_uid/migration_extension.rb
81
- test/config/database.yml.example
82
- test/global_uid_test.rb
83
- test/test_helper.rb
84
- ]
85
- # = MANIFEST =
86
-
87
- ## Test files will be grabbed from the file list. Make sure the path glob
88
- ## matches what you actually use.
89
- s.test_files = s.files.select { |path| path =~ /^test\/(test_.*|.*_test)\.rb/ }
90
- end
@@ -1,20 +0,0 @@
1
- test:
2
- adapter: mysql
3
- encoding: utf8
4
- database: global_uid_test
5
- username: root
6
- password:
7
-
8
- test_id_server_1:
9
- adapter: mysql
10
- encoding: utf8
11
- database: global_uid_test_id_server_1
12
- username: root
13
- password:
14
-
15
- test_id_server_2:
16
- adapter: mysql
17
- encoding: utf8
18
- database: global_uid_test_id_server_2
19
- username: root
20
- password:
@@ -1,475 +0,0 @@
1
- require 'test_helper'
2
-
3
- class CreateWithNoParams < ActiveRecord::Migration
4
- group :change if self.respond_to?(:group)
5
-
6
- def self.up
7
- create_table :with_global_uids do |t|
8
- t.string :description
9
- end
10
- end
11
-
12
- def self.down
13
- drop_table :with_global_uids
14
- end
15
- end
16
-
17
- class CreateWithExplicitUidTrue < ActiveRecord::Migration
18
- group :change if self.respond_to?(:group)
19
-
20
- def self.up
21
- create_table :with_global_uids, :use_global_uid => true do |t|
22
- t.string :description
23
- end
24
- end
25
-
26
- def self.down
27
- drop_table :with_global_uids, :use_global_uid => true
28
- end
29
- end
30
-
31
- class CreateWithNamedID < ActiveRecord::Migration
32
- group :change if self.respond_to?(:group)
33
-
34
- def self.up
35
- create_table :with_global_uids, :id => 'hello' do |t|
36
- t.string :description
37
- end
38
- end
39
-
40
- def self.down
41
- drop_table :with_global_uids
42
- end
43
- end
44
-
45
- class CreateWithoutGlobalUIDs < ActiveRecord::Migration
46
- group :change if self.respond_to?(:group)
47
-
48
- def self.up
49
- create_table :without_global_uids, :use_global_uid => false do |t|
50
- t.string :description
51
- end
52
- end
53
-
54
- def self.down
55
- drop_table :without_global_uids, :use_global_uid => false
56
- end
57
- end
58
-
59
- class WithGlobalUID < ActiveRecord::Base
60
- end
61
-
62
- class WithoutGlobalUID < ActiveRecord::Base
63
- end
64
-
65
- class Parent < ActiveRecord::Base
66
- def self.reset
67
- @global_uid_disabled = nil
68
- end
69
- end
70
-
71
- class ParentSubclass < Parent
72
- end
73
-
74
- class ParentSubclassSubclass < ParentSubclass
75
- end
76
-
77
- class GlobalUIDTest < ActiveSupport::TestCase
78
- ActiveRecord::Migration.verbose = false
79
-
80
- context "#global_uid_disabled" do
81
- setup do
82
- [ Parent, ParentSubclass, ParentSubclassSubclass ].each { |k| k.reset }
83
- end
84
-
85
- should "default to the parent value or false" do
86
- assert !ParentSubclass.global_uid_disabled
87
-
88
- ParentSubclass.disable_global_uid
89
- assert ParentSubclass.global_uid_disabled
90
- assert ParentSubclassSubclass.global_uid_disabled
91
-
92
- ParentSubclass.reset
93
- assert !ParentSubclass.global_uid_disabled
94
- assert ParentSubclassSubclass.global_uid_disabled
95
-
96
- ParentSubclassSubclass.reset
97
- assert !ParentSubclass.global_uid_disabled
98
- assert !ParentSubclassSubclass.global_uid_disabled
99
- end
100
- end
101
-
102
- context "migrations" do
103
- setup do
104
- restore_defaults!
105
- reset_connections!
106
- drop_old_test_tables!
107
- end
108
-
109
- context "without explicit parameters" do
110
- context "with global-uid enabled" do
111
- setup do
112
- GlobalUid::Base.global_uid_options[:disabled] = false
113
- GlobalUid::Base.global_uid_options[:storage_engine] = "InnoDB"
114
- CreateWithNoParams.up
115
- @create_table = show_create_sql(WithGlobalUID, "with_global_uids").split("\n")
116
- end
117
-
118
- should "create the global_uids table" do
119
- GlobalUid::Base.with_connections do |cx|
120
- assert cx.table_exists?('with_global_uids_ids')
121
- end
122
- end
123
-
124
- should "create global_uids tables with matching ids" do
125
- GlobalUid::Base.with_connections do |cx|
126
- foo = cx.select_all("select id from with_global_uids_ids")
127
- assert(foo.first['id'].to_i == 1)
128
- end
129
- end
130
-
131
- should "create tables with the given storage_engine" do
132
- GlobalUid::Base.with_connections do |cx|
133
- foo = cx.select_all("show create table with_global_uids_ids")
134
- assert_match /ENGINE=InnoDB/, foo.first.values.join
135
- end
136
-
137
- end
138
-
139
- should "tear off the auto_increment part of the primary key from the created table" do
140
- id_line = @create_table.grep(/\`id\` int/i).first
141
- assert_no_match /auto_increment/i, id_line
142
- end
143
-
144
- should "create a primary key on id" do
145
- assert @create_table.grep(/primary key/i).size > 0
146
- end
147
-
148
- teardown do
149
- CreateWithNoParams.down
150
- end
151
- end
152
-
153
- context "dropping a table" do
154
- should "not drop the global-uid tables" do
155
- CreateWithNoParams.up
156
- GlobalUid::Base.with_connections do |cx|
157
- assert cx.table_exists?('with_global_uids_ids')
158
- end
159
-
160
- CreateWithNoParams.down
161
- GlobalUid::Base.with_connections do |cx|
162
- assert cx.table_exists?('with_global_uids_ids')
163
- end
164
- end
165
- end
166
-
167
- context "with global-uid disabled, globally" do
168
- setup do
169
- GlobalUid::Base.global_uid_options[:disabled] = true
170
- CreateWithNoParams.up
171
- end
172
-
173
- should "not create the global_uids table" do
174
- GlobalUid::Base.with_connections do |cx|
175
- assert !cx.table_exists?('with_global_uids_ids')
176
- end
177
- end
178
-
179
- teardown do
180
- CreateWithNoParams.down
181
- GlobalUid::Base.global_uid_options[:disabled] = false
182
- end
183
- end
184
-
185
- context "with a named ID key" do
186
- setup do
187
- CreateWithNamedID.up
188
- end
189
-
190
- should "preserve the name of the ID key" do
191
- @create_table = show_create_sql(WithGlobalUID, "with_global_uids").split("\n")
192
- assert(@create_table.grep(/hello.*int/i))
193
- assert(@create_table.grep(/primary key.*hello/i))
194
- end
195
-
196
- teardown do
197
- CreateWithNamedID.down
198
- end
199
- end
200
- end
201
-
202
- context "with :use_global_uid => true" do
203
- context "dropping a table" do
204
- should "drop the global-uid tables" do
205
- CreateWithExplicitUidTrue.up
206
- GlobalUid::Base.with_connections do |cx|
207
- assert cx.table_exists?('with_global_uids_ids')
208
- end
209
-
210
- CreateWithExplicitUidTrue.down
211
- GlobalUid::Base.with_connections do |cx|
212
- assert !cx.table_exists?('with_global_uids_ids')
213
- end
214
- end
215
- end
216
- end
217
-
218
- context "with global-uid disabled in the migration" do
219
- setup do
220
- CreateWithoutGlobalUIDs.up
221
- @create_table = show_create_sql(WithoutGlobalUID, "without_global_uids").split("\n")
222
- end
223
-
224
- should "not create the global_uids table" do
225
- GlobalUid::Base.with_connections do |cx|
226
- assert !cx.table_exists?('without_global_uids_ids')
227
- end
228
- end
229
-
230
- should "create standard auto-increment tables" do
231
- id_line = @create_table.grep(/.id. int/i).first
232
- assert_match /auto_increment/i, id_line
233
- end
234
-
235
- teardown do
236
- CreateWithoutGlobalUIDs.down
237
- end
238
- end
239
- end
240
-
241
- context "With GlobalUID" do
242
- setup do
243
- reset_connections!
244
- drop_old_test_tables!
245
- restore_defaults!
246
- CreateWithNoParams.up
247
- CreateWithoutGlobalUIDs.up
248
- end
249
-
250
- context "normally" do
251
- should "get a unique id" do
252
- test_unique_ids
253
- end
254
-
255
- should "get bulk ids" do
256
- res = GlobalUid::Base.get_many_uids_for_class(WithGlobalUID, 10)
257
- assert res.size == 10
258
- res += GlobalUid::Base.get_many_uids_for_class(WithGlobalUID, 10)
259
- assert res.uniq.size == 20
260
- # starting value of 1 with a step of 5, so we should get 6,11,16...
261
- res.each_with_index do |val, i|
262
- assert_equal val, ((i + 1) * 5) + 1
263
- end
264
- end
265
- end
266
-
267
- context "reserving ids" do
268
- should "get 10 in bulk" do
269
- WithGlobalUID.with_reserved_global_uids(10) do
270
- WithGlobalUID.create!
271
- # now we should be able to run without ever touching the cx again
272
- GlobalUid::Base.get_connections.each.expects(:insert).never
273
- GlobalUid::Base.get_connections.each.expects(:select_value).never
274
- 9.times { WithGlobalUID.create! }
275
- end
276
-
277
- GlobalUid::Base.get_connections.first.expects(:insert).once.returns(50)
278
- WithGlobalUID.create!
279
- end
280
- end
281
-
282
- context "With a timing out server" do
283
- setup do
284
- reset_connections!
285
- @a_decent_cx = GlobalUid::Base.new_connection(GlobalUid::Base.global_uid_servers.first, 50, 1, 5, true)
286
- ActiveRecord::Base.stubs(:mysql_connection).raises(GlobalUid::ConnectionTimeoutException).then.returns(@a_decent_cx)
287
- @connections = GlobalUid::Base.get_connections
288
- end
289
-
290
- should "limp along with one functioning server" do
291
- assert @connections.include?(@a_decent_cx)
292
- assert_equal GlobalUid::Base.global_uid_servers.size - 1, @connections.size, "get_connections size"
293
- end
294
-
295
- should "eventually retry the connection and get it back in place" do
296
- # clear the state machine expectation
297
- ActiveRecord::Base.mysql_connection rescue nil
298
- ActiveRecord::Base.mysql_connection rescue nil
299
-
300
- awhile = Time.now + 10.hours
301
- Time.stubs(:now).returns(awhile)
302
-
303
- assert GlobalUid::Base.get_connections.size == GlobalUid::Base.global_uid_servers.size
304
-
305
- end
306
-
307
- should "get some unique ids" do
308
- test_unique_ids
309
- end
310
- end
311
-
312
- context "With a server timing out on query" do
313
- setup do
314
- reset_connections!
315
- @old_size = GlobalUid::Base.get_connections.size # prime them
316
- GlobalUid::Base.get_connections.first.stubs(:insert).raises(GlobalUid::TimeoutException)
317
- # trigger the failure -- have to do it it a bunch of times, as one call might not hit the server
318
- # Even so there's a 1/(2^32) possibility of this test failing.
319
- 32.times do WithGlobalUID.create! end
320
- end
321
-
322
- should "pull the server out of the pool" do
323
- assert GlobalUid::Base.get_connections.size == @old_size - 1
324
- end
325
-
326
- should "get ids from the remaining server" do
327
- test_unique_ids
328
- end
329
-
330
- should "eventually retry the connection" do
331
- awhile = Time.now + 10.hours
332
- Time.stubs(:now).returns(awhile)
333
-
334
- assert GlobalUid::Base.get_connections.size == GlobalUid::Base.global_uid_servers.size
335
- end
336
- end
337
-
338
- context "With both servers throwing exceptions" do
339
- setup do
340
- # would prefer to do the below, but need Mocha 0.9.10 to do so
341
- # ActiveRecord::ConnectionAdapters::MysqlAdapter.any_instance.stubs(:execute).raises(ActiveRecord::StatementInvalid)
342
- GlobalUid::Base.with_connections do |cx|
343
- cx.stubs(:insert).raises(ActiveRecord::StatementInvalid)
344
- end
345
- end
346
-
347
- should "raise a NoServersAvailableException" do
348
- assert_raises(GlobalUid::NoServersAvailableException) do
349
- WithGlobalUID.create!
350
- end
351
- end
352
-
353
- should "retry the servers immediately after failure" do
354
- assert_raises(GlobalUid::NoServersAvailableException) do
355
- WithGlobalUID.create!
356
- end
357
-
358
- assert WithGlobalUID.create!
359
- end
360
- end
361
-
362
-
363
- context "with per-process_affinity" do
364
- setup do
365
- GlobalUid::Base.global_uid_options[:per_process_affinity] = true
366
- end
367
-
368
- should "increment sequentially" do
369
- last_id = 0
370
- 10.times do
371
- this_id = WithGlobalUID.create!.id
372
- assert this_id > last_id
373
- end
374
- end
375
-
376
- teardown do
377
- GlobalUid::Base.global_uid_options[:per_process_affinity] = false
378
- end
379
- end
380
-
381
- context "with global-uid disabled" do
382
- setup do
383
- WithoutGlobalUID.disable_global_uid
384
- end
385
-
386
- should "never call various unsafe methods" do
387
- GlobalUid::Base.expects(:new_connection).never
388
- GlobalUid::Base.expects(:get_uid_for_class).never
389
- WithoutGlobalUID.expects(:generate_uid).never
390
- WithoutGlobalUID.expects(:ensure_global_uid).never
391
- GlobalUid::Base.expects(:get_uid_for_class).never
392
- end
393
-
394
- teardown do
395
- end
396
- end
397
-
398
- teardown do
399
- mocha_teardown # tear down mocha early to prevent some of this being tied to mocha expectations
400
- reset_connections!
401
- CreateWithNoParams.down
402
- CreateWithoutGlobalUIDs.down
403
- end
404
- end
405
-
406
- context "In dry-run mode" do
407
- setup do
408
- reset_connections!
409
- drop_old_test_tables!
410
- GlobalUid::Base.global_uid_options[:dry_run] = true
411
- CreateWithNoParams.up
412
- end
413
-
414
- should "create a normal looking table" do
415
-
416
- end
417
-
418
- should "increment normally1" do
419
- (1..10).each do |i|
420
- assert_equal i, WithGlobalUID.create!.id
421
- end
422
- end
423
-
424
- should "insert into the UID servers nonetheless" do
425
- GlobalUid::Base.expects(:get_uid_for_class).at_least(10)
426
- 10.times { WithGlobalUID.create! }
427
- end
428
-
429
- should "log the results" do
430
- ActiveRecord::Base.logger.expects(:info).at_least(10)
431
- 10.times { WithGlobalUID.create! }
432
- end
433
-
434
- teardown do
435
- reset_connections!
436
- CreateWithNoParams.down
437
- GlobalUid::Base.global_uid_options[:dry_run] = false
438
- end
439
- end
440
-
441
- private
442
- def test_unique_ids
443
- seen = {}
444
- (0..10).each do
445
- foo = WithGlobalUID.new
446
- foo.save
447
- assert !foo.id.nil?
448
- assert foo.description.nil?
449
- assert !seen.has_key?(foo.id)
450
- seen[foo.id] = 1
451
- end
452
- end
453
-
454
- def drop_old_test_tables!
455
- GlobalUid::Base.with_connections do |cx|
456
- cx.execute("DROP TABLE IF exists with_global_uids_ids")
457
- end
458
- end
459
-
460
- def reset_connections!
461
- GlobalUid::Base.class_eval "@@servers = nil"
462
- end
463
-
464
- def restore_defaults!
465
- GlobalUid::Base.global_uid_options[:disabled] = false
466
- GlobalUid::Base.global_uid_options[:use_server_variables] = true
467
- GlobalUid::Base.global_uid_options[:dry_run] = false
468
- end
469
-
470
- def show_create_sql(klass, table)
471
- klass.connection.select_rows("show create table #{table}")[0][1]
472
- end
473
- end
474
-
475
-
data/test/test_helper.rb DELETED
@@ -1,34 +0,0 @@
1
- require 'rubygems'
2
-
3
- require 'bundler'
4
- Bundler.setup
5
- Bundler.setup(:test)
6
-
7
- require 'ruby-debug'
8
- require "active_record"
9
- require "active_support"
10
- require "active_support/test_case"
11
- require "shoulda"
12
- require "mocha"
13
- require "global_uid"
14
-
15
- GlobalUid::Base.global_uid_options = {
16
- :use_server_variables => true,
17
- :disabled => false,
18
- :id_servers => [
19
- "test_id_server_1",
20
- "test_id_server_2"
21
- ]
22
- }
23
-
24
- yaml = YAML::load(IO.read(File.dirname(__FILE__) + "/config/database.yml"))
25
-
26
- if !Gem::Specification.find_all_by_name("mysql2").empty?
27
- yaml.each do |k, v|
28
- v['adapter'] = 'mysql2'
29
- end
30
- end
31
-
32
- ActiveRecord::Base.configurations = yaml
33
- ActiveRecord::Base.establish_connection("test")
34
- ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/test.log")