class ActiveRecord::ConnectionAdapters::AuroraServerless::Client

Constants

CLIENT_OPTIONS

From AWS docs at amzn.to/35V6O8L

Attributes

affected_rows[R]
database[R]
last_id[R]
raw_client[R]
resource_arn[R]
secret_arn[R]

Public Class Methods

new(database, resource_arn, secret_arn, options = {}) click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 12
def initialize(database, resource_arn, secret_arn, options = {})
  @database = database
  @resource_arn = resource_arn
  @secret_arn = secret_arn
  @raw_client = Aws::RDSDataService::Client.new(client_options(options))
  @transactions = []
  @affected_rows = 0
  @debug_transactions = false # Development toggle.
end

Public Instance Methods

begin_db_transaction() click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 58
def begin_db_transaction
  id = raw_client.begin_transaction({
    database: database,
    secret_arn: secret_arn,
    resource_arn: resource_arn
  }).try(:transaction_id)
  debug_transactions 'BEGIN', id
  @transactions.unshift(id) if id
  true
end
commit_db_transaction() click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 69
def commit_db_transaction
  id = @transactions.shift
  return unless id
  debug_transactions 'COMMIT', id
  raw_client.commit_transaction({
    secret_arn: secret_arn,
    resource_arn: resource_arn,
    transaction_id: id
  })
  true
rescue
  @transactions.unshift(id) # For imminent rollback.
end
exec_rollback_db_transaction() click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 83
def exec_rollback_db_transaction
  id = @transactions.shift
  return unless id
  debug_transactions 'ROLLBACK', id
  raw_client.rollback_transaction({
    secret_arn: secret_arn,
    resource_arn: resource_arn,
    transaction_id: id
  })
  true
end
execute_statement(sql) click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 34
def execute_statement(sql)
  id = @transactions.first
  debug_transactions "EXECUTE: #{sql}", id
  raw_client.execute_statement({
    sql: sql,
    database: database,
    secret_arn: secret_arn,
    resource_arn: resource_arn,
    include_result_metadata: true,
    transaction_id: id
  }).tap do |r|
    @connected = true
    @affected_rows = affected_rows_result(r)
    @last_id = last_id_result(r)
  end
rescue Exception => e
  if id && e.message == "Transaction #{id} is not found"
    @transactions.shift
    retry
  else
    raise e
  end
end
execute_statement_retry(sql) click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 26
def execute_statement_retry(sql)
  if @connected
    execute_statement(sql)
  else
    auto_paused_retry { execute_statement(sql) }
  end
end
inspect() click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 22
def inspect
  "#<#{self.class} database: #{database.inspect}, raw_client: #{raw_client.inspect}>"
end

Private Instance Methods

affected_rows_result(result) click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 101
def affected_rows_result(result)
  result.number_of_records_updated || 0
end
auto_paused_retry() { || ... } click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 112
def auto_paused_retry
  error_klass = Aws::RDSDataService::Errors::BadRequestException
  error_msg = /last packet sent successfully to the server was/
  retry_msg = 'Aurora auto paused, retrying...'
  on_retry = Proc.new { sleep(1) ; ::Rails.logger.info(retry_msg)  }
  Retriable.retriable({
    on: { error_klass => error_msg },
    on_retry: on_retry,
    tries: auto_paused_retry_count
  }) { yield }
end
auto_paused_retry_count() click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 124
def auto_paused_retry_count
  10
end
client_options(options) click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 97
def client_options(options)
  options.slice(*CLIENT_OPTIONS)
end
debug_transactions(name, id = 'NOID') click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 128
def debug_transactions(name, id = 'NOID')
  return unless @debug_transactions
  ActiveRecord::Base.logger.debug "  \e[36m#{name} #{id} #{object_id}\e[0m"
end
last_id_result(result) click to toggle source
# File lib/active_record/connection_adapters/aurora_serverless/client.rb, line 105
def last_id_result(result)
  fields = result.generated_fields || []
  field = fields.last
  return unless field
  field.long_value || field.string_value || field.double_value
end