global_uid 1.4.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/global_uid/active_record_extension.rb +4 -0
- data/lib/global_uid/base.rb +2 -10
- data/lib/global_uid/server_variables.rb +29 -0
- data/lib/global_uid.rb +3 -1
- metadata +29 -28
- data/Appraisals +0 -12
- data/Gemfile +0 -6
- data/README.md +0 -130
- data/Rakefile +0 -151
- data/gemfiles/rails2.gemfile +0 -9
- data/gemfiles/rails2.gemfile.lock +0 -53
- data/gemfiles/rails2mysql2.gemfile.lock +0 -65
- data/gemfiles/rails3.gemfile +0 -9
- data/gemfiles/rails3.gemfile.lock +0 -66
- data/global_uid.gemspec +0 -90
- data/test/config/database.yml.example +0 -20
- data/test/global_uid_test.rb +0 -475
- data/test/test_helper.rb +0 -34
data/lib/global_uid/base.rb
CHANGED
@@ -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
|
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
|
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.
|
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.
|
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:
|
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
|
-
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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:
|
187
|
+
version: '0'
|
185
188
|
requirements: []
|
186
|
-
rubyforge_project:
|
187
|
-
rubygems_version: 1.8.
|
189
|
+
rubyforge_project:
|
190
|
+
rubygems_version: 1.8.23.2
|
188
191
|
signing_key:
|
189
|
-
specification_version:
|
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
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
|
data/gemfiles/rails2.gemfile
DELETED
@@ -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
|
data/gemfiles/rails3.gemfile
DELETED
@@ -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:
|
data/test/global_uid_test.rb
DELETED
@@ -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")
|