global_uid 4.0.0.beta1 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a02789fdd302a6dbc207c590c60ce5b5909f8430e3432813af90d0373efd71b
4
- data.tar.gz: 4cf5cd96f7b8855b546a1741c67dac5db6bb9b42cca3105bbe741423a2f2e66e
3
+ metadata.gz: 98380377dabc356230fb10d765ea683777d64e89626597fd030c848f4e3e2048
4
+ data.tar.gz: c361fed08769004591c58f40ca4b79d67f6aec19e0e1f22d2bb357f9392edc55
5
5
  SHA512:
6
- metadata.gz: 9e36b732bbea40d81423498b9ec9365e39688601691524b615a9b1cc0955b5dbcbf7b9788128bcb5673b08ccd37c49b44a7990d8a62f578358cd9ca8116d17fb
7
- data.tar.gz: 73b1d6ff9808d94c14e1618b7da2137e0ad9c2b02442941b788519ebdc77daec7bfc8be67715ec16294062ea8ae334c1b437a198342f096623bd4f124585385c
6
+ metadata.gz: '0298584b7b7a01105723caffe1770b4c1a448798335f38a2de67cce712031d9232267f4fdefba1fc7e2d642ec624c750e5b6b24d5ea1c0e57639fc40af588015'
7
+ data.tar.gz: 7f69e85213c62c30b14679993fc86eedf58e737b31557812a3de53a607f246b755287ddf9ded039836069cf3ed41572acf341ed298bfba56f23c5ccc84d76f92
@@ -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.configuration.disabled?
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
@@ -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
- validate_connection_increment
10
+ @table_name = table_name
11
11
  end
12
12
 
13
- def allocate_one(table)
14
- identifier = connection.insert("REPLACE INTO #{table} (stub) VALUES ('a')")
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(table, count:)
18
+ def allocate_many(count:)
19
19
  return [] unless count > 0
20
20
 
21
- increment_by = validate_connection_increment
21
+ increment_by = connection.select_value("SELECT @@auto_increment_increment")
22
22
 
23
- start_id = connection.insert("REPLACE INTO #{table} (stub) VALUES " + (["('a')"] * count).join(','))
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
@@ -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 = !(GlobalUid.configuration.disabled? || options[:use_global_uid] == false)
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] || "bigint(21) UNSIGNED",
24
- start_id: options[:start_id] || 1,
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 !GlobalUid.configuration.disabled? && options[:use_global_uid] == true
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)
@@ -7,7 +7,7 @@ module GlobalUid
7
7
  @connection = nil
8
8
  @name = name
9
9
  @retry_at = nil
10
- @allocator = nil
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
- @allocator = Allocator.new(incrementing_by: increment_by, connection: @connection) if active?
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
- @allocator = nil
45
+ @allocators = {}
46
46
  end
47
47
 
48
- def create_uid_table!(name:, uid_type:, start_id:, storage_engine:)
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.allocate_one(klass.global_uid_table)
72
+ allocator(klass).allocate_one
70
73
  else
71
- allocator.allocate_many(klass.global_uid_table, count: count)
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, :allocator
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
- raise "No id server '#{name}' configured in database.yml" unless ActiveRecord::Base.configurations.to_h.has_key?(name)
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.0.0.beta1
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: 2020-04-28 00:00:00.000000000 Z
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.1'
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.1'
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: 1.3.1
241
+ version: '0'
241
242
  requirements: []
242
- rubygems_version: 3.1.2
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: []