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 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: []