global_uid 4.0.0.beta1 → 4.1.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.
- checksums.yaml +4 -4
- data/lib/global_uid.rb +16 -0
- data/lib/global_uid/active_record_extension.rb +3 -3
- data/lib/global_uid/allocator.rb +10 -28
- data/lib/global_uid/base.rb +8 -0
- data/lib/global_uid/configuration.rb +0 -1
- data/lib/global_uid/migration_extension.rb +4 -5
- data/lib/global_uid/server.rb +45 -13
- data/lib/global_uid/test_support.rb +44 -0
- metadata +11 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98380377dabc356230fb10d765ea683777d64e89626597fd030c848f4e3e2048
|
4
|
+
data.tar.gz: c361fed08769004591c58f40ca4b79d67f6aec19e0e1f22d2bb357f9392edc55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0298584b7b7a01105723caffe1770b4c1a448798335f38a2de67cce712031d9232267f4fdefba1fc7e2d642ec624c750e5b6b24d5ea1c0e57639fc40af588015'
|
7
|
+
data.tar.gz: 7f69e85213c62c30b14679993fc86eedf58e737b31557812a3de53a607f246b755287ddf9ded039836069cf3ed41572acf341ed298bfba56f23c5ccc84d76f92
|
data/lib/global_uid.rb
CHANGED
@@ -23,6 +23,22 @@ module GlobalUid
|
|
23
23
|
yield configuration if block_given?
|
24
24
|
end
|
25
25
|
|
26
|
+
def self.disable!
|
27
|
+
self.configuration.disabled = true
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.enable!
|
31
|
+
self.configuration.disabled = false
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.enabled?
|
35
|
+
!self.disabled?
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.disabled?
|
39
|
+
self.configuration.disabled
|
40
|
+
end
|
41
|
+
|
26
42
|
# @private
|
27
43
|
def self.reset_configuration
|
28
44
|
@configuration = nil
|
@@ -8,7 +8,7 @@ module GlobalUid
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def global_uid_before_create
|
11
|
-
return if GlobalUid.
|
11
|
+
return if GlobalUid.disabled?
|
12
12
|
return if self.class.global_uid_disabled
|
13
13
|
|
14
14
|
self.id = self.class.generate_uid
|
@@ -35,7 +35,7 @@ module GlobalUid
|
|
35
35
|
|
36
36
|
def generate_many_uids(count)
|
37
37
|
GlobalUid::Base.with_servers do |server|
|
38
|
-
return server.allocate(self, count: count)
|
38
|
+
return Array(server.allocate(self, count: count))
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -48,7 +48,7 @@ module GlobalUid
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def global_uid_table
|
51
|
-
GlobalUid::Base.id_table_from_name(self.table_name)
|
51
|
+
@_global_uid_table ||= GlobalUid::Base.id_table_from_name(self.table_name)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
data/lib/global_uid/allocator.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
module GlobalUid
|
2
2
|
class Allocator
|
3
|
-
attr_reader :recent_allocations, :max_window_size, :incrementing_by, :connection
|
3
|
+
attr_reader :recent_allocations, :max_window_size, :incrementing_by, :connection, :table_name
|
4
4
|
|
5
|
-
def initialize(incrementing_by:, connection:)
|
5
|
+
def initialize(incrementing_by:, connection:, table_name:)
|
6
6
|
@recent_allocations = []
|
7
7
|
@max_window_size = 5
|
8
8
|
@incrementing_by = incrementing_by
|
9
9
|
@connection = connection
|
10
|
-
|
10
|
+
@table_name = table_name
|
11
11
|
end
|
12
12
|
|
13
|
-
def allocate_one
|
14
|
-
identifier = connection.insert("REPLACE INTO #{
|
13
|
+
def allocate_one
|
14
|
+
identifier = connection.insert("REPLACE INTO #{table_name} (stub) VALUES ('a')")
|
15
15
|
allocate(identifier)
|
16
16
|
end
|
17
17
|
|
18
|
-
def allocate_many(
|
18
|
+
def allocate_many(count:)
|
19
19
|
return [] unless count > 0
|
20
20
|
|
21
|
-
increment_by =
|
21
|
+
increment_by = connection.select_value("SELECT @@auto_increment_increment")
|
22
22
|
|
23
|
-
start_id = connection.insert("REPLACE INTO #{
|
23
|
+
start_id = connection.insert("REPLACE INTO #{table_name} (stub) VALUES " + (["('a')"] * count).join(','))
|
24
24
|
identifiers = start_id.step(start_id + (count - 1) * increment_by, increment_by).to_a
|
25
25
|
identifiers.each { |identifier| allocate(identifier) }
|
26
26
|
identifiers
|
@@ -34,8 +34,8 @@ module GlobalUid
|
|
34
34
|
|
35
35
|
if !valid_allocation?
|
36
36
|
db_increment = connection.select_value("SELECT @@auto_increment_increment")
|
37
|
-
message = "Configured: '#{incrementing_by}', Found: '#{db_increment}' on '#{connection.current_database}'. Recently allocated IDs: #{recent_allocations}"
|
38
|
-
alert(InvalidIncrementException.new(message))
|
37
|
+
message = "Configured: '#{incrementing_by}', Found: '#{db_increment}' on '#{connection.current_database}'. Recently allocated IDs: #{recent_allocations} using table '#{table_name}'"
|
38
|
+
GlobalUid::Base.alert(InvalidIncrementException.new(message))
|
39
39
|
end
|
40
40
|
|
41
41
|
identifier
|
@@ -47,23 +47,5 @@ module GlobalUid
|
|
47
47
|
(identifier - recent_allocations[0]) % incrementing_by == 0
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
51
|
-
def validate_connection_increment
|
52
|
-
db_increment = connection.select_value("SELECT @@auto_increment_increment")
|
53
|
-
|
54
|
-
if db_increment != incrementing_by
|
55
|
-
alert(InvalidIncrementException.new("Configured: '#{incrementing_by}', Found: '#{db_increment}' on '#{connection.current_database}'"))
|
56
|
-
end
|
57
|
-
|
58
|
-
db_increment
|
59
|
-
end
|
60
|
-
|
61
|
-
def alert(exception)
|
62
|
-
if GlobalUid.configuration.suppress_increment_exceptions?
|
63
|
-
GlobalUid.configuration.notifier.call(exception)
|
64
|
-
else
|
65
|
-
raise exception
|
66
|
-
end
|
67
|
-
end
|
68
50
|
end
|
69
51
|
end
|
data/lib/global_uid/base.rb
CHANGED
@@ -68,5 +68,13 @@ module GlobalUid
|
|
68
68
|
def self.id_table_from_name(name)
|
69
69
|
"#{name}_ids".to_sym
|
70
70
|
end
|
71
|
+
|
72
|
+
def self.alert(exception)
|
73
|
+
if GlobalUid.configuration.suppress_increment_exceptions?
|
74
|
+
GlobalUid.configuration.notifier.call(exception)
|
75
|
+
else
|
76
|
+
raise exception
|
77
|
+
end
|
78
|
+
end
|
71
79
|
end
|
72
80
|
end
|
@@ -11,7 +11,6 @@ module GlobalUid
|
|
11
11
|
attr_accessor :suppress_increment_exceptions
|
12
12
|
attr_accessor :storage_engine
|
13
13
|
|
14
|
-
alias_method :disabled?, :disabled
|
15
14
|
alias_method :connection_shuffling?, :connection_shuffling
|
16
15
|
alias_method :suppress_increment_exceptions?, :suppress_increment_exceptions
|
17
16
|
|
@@ -3,7 +3,7 @@ module GlobalUid
|
|
3
3
|
module MigrationExtension
|
4
4
|
|
5
5
|
def create_table(name, options = {}, &blk)
|
6
|
-
uid_enabled =
|
6
|
+
uid_enabled = GlobalUid.enabled? && options[:use_global_uid] != false
|
7
7
|
|
8
8
|
# rules for stripping out auto_increment -- enabled and not a "PK-less" table
|
9
9
|
remove_auto_increment = uid_enabled && !(options[:id] == false)
|
@@ -20,9 +20,8 @@ module GlobalUid
|
|
20
20
|
GlobalUid::Base.with_servers do |server|
|
21
21
|
server.create_uid_table!(
|
22
22
|
name: id_table_name,
|
23
|
-
uid_type: options[:uid_type]
|
24
|
-
start_id: options[:start_id]
|
25
|
-
storage_engine: GlobalUid.configuration.storage_engine
|
23
|
+
uid_type: options[:uid_type],
|
24
|
+
start_id: options[:start_id]
|
26
25
|
)
|
27
26
|
end
|
28
27
|
end
|
@@ -30,7 +29,7 @@ module GlobalUid
|
|
30
29
|
end
|
31
30
|
|
32
31
|
def drop_table(name, options = {})
|
33
|
-
if
|
32
|
+
if GlobalUid.enabled? && options[:use_global_uid] == true
|
34
33
|
id_table_name = options[:global_uid_table] || GlobalUid::Base.id_table_from_name(name)
|
35
34
|
GlobalUid::Base.with_servers do |server|
|
36
35
|
server.drop_uid_table!(name: id_table_name)
|
data/lib/global_uid/server.rb
CHANGED
@@ -7,7 +7,7 @@ module GlobalUid
|
|
7
7
|
@connection = nil
|
8
8
|
@name = name
|
9
9
|
@retry_at = nil
|
10
|
-
@
|
10
|
+
@allocators = {}
|
11
11
|
@increment_by = increment_by
|
12
12
|
@connection_retry = connection_retry
|
13
13
|
@connection_timeout = connection_timeout
|
@@ -19,7 +19,7 @@ module GlobalUid
|
|
19
19
|
@connection = mysql2_connection(name)
|
20
20
|
|
21
21
|
begin
|
22
|
-
|
22
|
+
validate_connection_increment if active?
|
23
23
|
rescue InvalidIncrementException => e
|
24
24
|
GlobalUid.configuration.notifier.call(e)
|
25
25
|
disconnect!
|
@@ -42,16 +42,19 @@ module GlobalUid
|
|
42
42
|
|
43
43
|
def disconnect!
|
44
44
|
@connection = nil
|
45
|
-
@
|
45
|
+
@allocators = {}
|
46
46
|
end
|
47
47
|
|
48
|
-
def create_uid_table!(name:, uid_type
|
48
|
+
def create_uid_table!(name:, uid_type: nil, start_id: nil)
|
49
|
+
uid_type ||= "bigint(21) UNSIGNED"
|
50
|
+
start_id ||= 1
|
51
|
+
|
49
52
|
connection.execute("CREATE TABLE IF NOT EXISTS `#{name}` (
|
50
53
|
`id` #{uid_type} NOT NULL AUTO_INCREMENT,
|
51
54
|
`stub` char(1) NOT NULL DEFAULT '',
|
52
55
|
PRIMARY KEY (`id`),
|
53
56
|
UNIQUE KEY `stub` (`stub`)
|
54
|
-
) ENGINE=#{storage_engine}")
|
57
|
+
) ENGINE=#{GlobalUid.configuration.storage_engine}")
|
55
58
|
|
56
59
|
# prime the pump on each server
|
57
60
|
connection.execute("INSERT IGNORE INTO `#{name}` VALUES(#{start_id}, 'a')")
|
@@ -66,16 +69,21 @@ module GlobalUid
|
|
66
69
|
# Timeout.timeout is unpredictable
|
67
70
|
Timeout.timeout(query_timeout, TimeoutException) do
|
68
71
|
if count == 1
|
69
|
-
allocator
|
72
|
+
allocator(klass).allocate_one
|
70
73
|
else
|
71
|
-
allocator.allocate_many(
|
74
|
+
allocator(klass).allocate_many(count: count)
|
72
75
|
end
|
73
76
|
end
|
74
77
|
end
|
75
78
|
|
76
79
|
private
|
77
80
|
|
78
|
-
attr_accessor :connection_retry, :connection_timeout, :retry_at, :increment_by, :query_timeout, :
|
81
|
+
attr_accessor :connection_retry, :connection_timeout, :retry_at, :increment_by, :query_timeout, :allocators
|
82
|
+
|
83
|
+
def allocator(klass)
|
84
|
+
table_name = klass.global_uid_table
|
85
|
+
@allocators[table_name] ||= Allocator.new(incrementing_by: increment_by, connection: connection, table_name: table_name)
|
86
|
+
end
|
79
87
|
|
80
88
|
def retry_connection?
|
81
89
|
return Time.now > retry_at if retry_at
|
@@ -85,11 +93,7 @@ module GlobalUid
|
|
85
93
|
end
|
86
94
|
|
87
95
|
def mysql2_connection(name)
|
88
|
-
|
89
|
-
config = ActiveRecord::Base.configurations.to_h[name]
|
90
|
-
c = config.symbolize_keys
|
91
|
-
|
92
|
-
raise "No global_uid support for adapter #{c[:adapter]}" if c[:adapter] != 'mysql2'
|
96
|
+
config = mysql2_config(name)
|
93
97
|
|
94
98
|
Timeout.timeout(connection_timeout, ConnectionTimeoutException) do
|
95
99
|
ActiveRecord::Base.mysql2_connection(config)
|
@@ -102,5 +106,33 @@ module GlobalUid
|
|
102
106
|
nil
|
103
107
|
end
|
104
108
|
|
109
|
+
if ActiveRecord.version < Gem::Version.new('6.1.0')
|
110
|
+
def mysql2_config(name)
|
111
|
+
raise "No id server '#{name}' configured in database.yml" unless ActiveRecord::Base.configurations.to_h.has_key?(name)
|
112
|
+
config = ActiveRecord::Base.configurations.to_h[name]
|
113
|
+
|
114
|
+
c = config.symbolize_keys
|
115
|
+
raise "No global_uid support for adapter #{c[:adapter]}" if c[:adapter] != 'mysql2'
|
116
|
+
|
117
|
+
config
|
118
|
+
end
|
119
|
+
else
|
120
|
+
def mysql2_config(name)
|
121
|
+
config = ActiveRecord::Base.configurations.configs_for(env_name: name, name: 'primary')
|
122
|
+
|
123
|
+
raise "No id server '#{name}' configured in database.yml" if config.nil?
|
124
|
+
raise "No global_uid support for adapter #{config.adapter}" if config.adapter != 'mysql2'
|
125
|
+
|
126
|
+
config.configuration_hash
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def validate_connection_increment
|
131
|
+
db_increment = connection.select_value("SELECT @@auto_increment_increment")
|
132
|
+
|
133
|
+
if db_increment != increment_by
|
134
|
+
GlobalUid::Base.alert(InvalidIncrementException.new("Configured: '#{increment_by}', Found: '#{db_increment}' on '#{connection.current_database}'"))
|
135
|
+
end
|
136
|
+
end
|
105
137
|
end
|
106
138
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module GlobalUid
|
2
|
+
module TestSupport
|
3
|
+
# Tables should be created through the MigrationExtension but
|
4
|
+
# if you want to manually create and drop the '_id' tables,
|
5
|
+
# you can do so via this module
|
6
|
+
class << self
|
7
|
+
def create_uid_tables(tables: [], uid_type: nil, start_id: nil)
|
8
|
+
return if GlobalUid.disabled?
|
9
|
+
|
10
|
+
GlobalUid::Base.with_servers do |server|
|
11
|
+
tables.each do |table|
|
12
|
+
server.create_uid_table!(
|
13
|
+
name: GlobalUid::Base.id_table_from_name(table),
|
14
|
+
uid_type: uid_type,
|
15
|
+
start_id: start_id
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def drop_uid_tables(tables: [])
|
22
|
+
return if GlobalUid.disabled?
|
23
|
+
|
24
|
+
GlobalUid::Base.with_servers do |server|
|
25
|
+
tables.each do |table|
|
26
|
+
server.drop_uid_table!(
|
27
|
+
name: GlobalUid::Base.id_table_from_name(table)
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def recreate_uid_tables(tables: [], uid_type: nil, start_id: nil)
|
34
|
+
return if GlobalUid.disabled?
|
35
|
+
|
36
|
+
drop_uid_tables(tables: tables)
|
37
|
+
create_uid_tables(tables: tables, uid_type: nil, start_id: start_id)
|
38
|
+
|
39
|
+
# Reset the servers, clearing any allocations from memory
|
40
|
+
GlobalUid::Base.disconnect!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: global_uid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Quorning
|
8
8
|
- Gabe Martin-Dempesy
|
9
9
|
- Pierre Schambacher
|
10
10
|
- Ben Osheroff
|
11
|
-
autorequire:
|
11
|
+
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2021-01-14 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activerecord
|
@@ -22,7 +22,7 @@ dependencies:
|
|
22
22
|
version: 4.2.0
|
23
23
|
- - "<"
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: '6.
|
25
|
+
version: '6.2'
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
28
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 4.2.0
|
33
33
|
- - "<"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '6.
|
35
|
+
version: '6.2'
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: activesupport
|
38
38
|
requirement: !ruby/object:Gem::Requirement
|
@@ -220,11 +220,12 @@ files:
|
|
220
220
|
- lib/global_uid/migration_extension.rb
|
221
221
|
- lib/global_uid/schema_dumper_extension.rb
|
222
222
|
- lib/global_uid/server.rb
|
223
|
+
- lib/global_uid/test_support.rb
|
223
224
|
homepage: https://github.com/zendesk/global_uid
|
224
225
|
licenses:
|
225
226
|
- MIT
|
226
227
|
metadata: {}
|
227
|
-
post_install_message:
|
228
|
+
post_install_message:
|
228
229
|
rdoc_options: []
|
229
230
|
require_paths:
|
230
231
|
- lib
|
@@ -235,12 +236,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
235
236
|
version: '2.4'
|
236
237
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
238
|
requirements:
|
238
|
-
- - "
|
239
|
+
- - ">="
|
239
240
|
- !ruby/object:Gem::Version
|
240
|
-
version:
|
241
|
+
version: '0'
|
241
242
|
requirements: []
|
242
|
-
rubygems_version: 3.
|
243
|
-
signing_key:
|
243
|
+
rubygems_version: 3.2.2
|
244
|
+
signing_key:
|
244
245
|
specification_version: 4
|
245
246
|
summary: GUID
|
246
247
|
test_files: []
|