class GlobalUid::Server
Attributes
allocators[RW]
connection[RW]
connection_retry[RW]
connection_timeout[RW]
increment_by[RW]
name[RW]
query_timeout[RW]
retry_at[RW]
Public Class Methods
new(name, increment_by:, connection_retry:, connection_timeout:, query_timeout:)
click to toggle source
# File lib/global_uid/server.rb, line 6 def initialize(name, increment_by:, connection_retry:, connection_timeout:, query_timeout:) @connection = nil @name = name @retry_at = nil @allocators = {} @increment_by = increment_by @connection_retry = connection_retry @connection_timeout = connection_timeout @query_timeout = query_timeout end
Public Instance Methods
active?()
click to toggle source
# File lib/global_uid/server.rb, line 31 def active? !disconnected? end
allocate(klass, count: 1)
click to toggle source
# File lib/global_uid/server.rb, line 67 def allocate(klass, count: 1) # TODO: Replace Timeout.timeout with DB level timeout # Timeout.timeout is unpredictable Timeout.timeout(query_timeout, TimeoutException) do if count == 1 allocator(klass).allocate_one else allocator(klass).allocate_many(count: count) end end end
connect()
click to toggle source
# File lib/global_uid/server.rb, line 17 def connect return @connection if active? || !retry_connection? @connection = mysql2_connection(name) begin validate_connection_increment if active? rescue InvalidIncrementException => e GlobalUid.configuration.notifier.call(e) disconnect! end @connection end
create_uid_table!(name:, uid_type: nil, start_id: nil)
click to toggle source
# File lib/global_uid/server.rb, line 48 def create_uid_table!(name:, uid_type: nil, start_id: nil) uid_type ||= "bigint(21) UNSIGNED" start_id ||= 1 connection.execute("CREATE TABLE IF NOT EXISTS `#{name}` ( `id` #{uid_type} NOT NULL AUTO_INCREMENT, `stub` char(1) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `stub` (`stub`) ) ENGINE=#{GlobalUid.configuration.storage_engine}") # prime the pump on each server connection.execute("INSERT IGNORE INTO `#{name}` VALUES(#{start_id}, 'a')") end
disconnect!()
click to toggle source
# File lib/global_uid/server.rb, line 43 def disconnect! @connection = nil @allocators = {} end
disconnected?()
click to toggle source
# File lib/global_uid/server.rb, line 35 def disconnected? @connection.nil? end
drop_uid_table!(name:)
click to toggle source
# File lib/global_uid/server.rb, line 63 def drop_uid_table!(name:) connection.execute("DROP TABLE IF EXISTS `#{name}`") end
update_retry_at(seconds)
click to toggle source
# File lib/global_uid/server.rb, line 39 def update_retry_at(seconds) @retry_at = Time.now + seconds end
Private Instance Methods
allocator(klass)
click to toggle source
# File lib/global_uid/server.rb, line 83 def allocator(klass) table_name = klass.global_uid_table @allocators[table_name] ||= Allocator.new(incrementing_by: increment_by, connection: connection, table_name: table_name) end
mysql2_config(name)
click to toggle source
# File lib/global_uid/server.rb, line 110 def mysql2_config(name) raise "No id server '#{name}' configured in database.yml" unless ActiveRecord::Base.configurations.to_h.has_key?(name) config = ActiveRecord::Base.configurations.to_h[name] c = config.symbolize_keys raise "No global_uid support for adapter #{c[:adapter]}" if c[:adapter] != 'mysql2' config end
mysql2_connection(name)
click to toggle source
# File lib/global_uid/server.rb, line 95 def mysql2_connection(name) config = mysql2_config(name) Timeout.timeout(connection_timeout, ConnectionTimeoutException) do ActiveRecord::Base.mysql2_connection(config) end rescue ConnectionTimeoutException => e GlobalUid.configuration.notifier.call(ConnectionTimeoutException.new("Timed out establishing a connection to #{name}")) nil rescue Exception => e GlobalUid.configuration.notifier.call(StandardError.new("establishing a connection to #{name}: #{e.message}")) nil end
retry_connection?()
click to toggle source
# File lib/global_uid/server.rb, line 88 def retry_connection? return Time.now > retry_at if retry_at update_retry_at(connection_retry) true end
validate_connection_increment()
click to toggle source
# File lib/global_uid/server.rb, line 130 def validate_connection_increment db_increment = connection.select_value("SELECT @@auto_increment_increment") if db_increment != increment_by GlobalUid::Base.alert(InvalidIncrementException.new("Configured: '#{increment_by}', Found: '#{db_increment}' on '#{connection.current_database}'")) end end