Skip to content

Commit

Permalink
Merge pull request #34 from joinhandshake/rails-7
Browse files Browse the repository at this point in the history
Update to support Rails 7.0
  • Loading branch information
davkutalek authored Aug 16, 2024
2 parents fedbfca + 03cb00b commit bd1cfdf
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 54 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:

strategy:
matrix:
ruby-version: ['2.6.10', '2.7.8', '3.0.6', '3.1.4']
ruby-version: ['2.7.8', '3.0.6', '3.1.4']

steps:
# Pin to this commit: v2
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Unreleased

## 1.5.0

Update to be Rails 7.0 compatible. Drops support for ruby 2.6 and Rails 6.0-

## 1.4.0

Update to be Rails 6.1 compatible
Expand Down
20 changes: 9 additions & 11 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
PATH
remote: .
specs:
knockoff (1.4.0)
activerecord (>= 6, < 7)
activesupport (>= 6, < 7)
knockoff (1.5.0)
activerecord (>= 6.1, < 7.1)
activesupport (>= 6.1, < 7.1)

GEM
remote: https://rubygems.org/
specs:
activemodel (6.1.7.8)
activesupport (= 6.1.7.8)
activerecord (6.1.7.8)
activemodel (= 6.1.7.8)
activesupport (= 6.1.7.8)
activesupport (6.1.7.8)
activemodel (7.0.8.4)
activesupport (= 7.0.8.4)
activerecord (7.0.8.4)
activemodel (= 7.0.8.4)
activesupport (= 7.0.8.4)
activesupport (7.0.8.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
concurrent-ruby (1.3.4)
diff-lcs (1.5.1)
i18n (1.14.5)
Expand Down Expand Up @@ -46,7 +45,6 @@ GEM
sqlite3 (1.5.4-x86_64-linux)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
zeitwerk (2.6.17)

PLATFORMS
aarch64-linux
Expand Down
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,29 @@ A gem for easily using read replicas.

## Supported Versions

Knockoff supports Rails 4, 5 and 6
| Knockoff version: | 1.0 | 1.1.0 | 1.1.1 | 1.4 | 1.5 |
| --- | --- | --- | --- | --- | --- |
| Ruby 2.2 | [x] | [ ] | [ ] | [ ] | [ ] |
| Ruby 2.3 | [x] | [x] | [ ] | [ ] | [ ] |
| Ruby 2.4 | [x] | [x] | [x] | [ ] | [ ] |
| Ruby 2.5 | [ ] | [x] | [x] | [ ] | [ ] |
| Ruby 2.6 | [ ] | [ ] | [x] | [x] | [ ] |
| Ruby 2.7 | [ ] | [ ] | [x] | [x] | [x] |
| Ruby 3.0 | [ ] | [ ] | [ ] | [x] | [x] |
| Ruby 3.1 | [ ] | [ ] | [ ] | [x] | [x] |

| Knockoff version: | 1.0 | 1.1.0 | 1.1.1 | 1.4 | 1.5 |
| --- | --- | --- | --- | --- | --- |
| Rails 4 | [x] | [x] | [ ] | [ ] | [ ] |
| Rails 5.0 | [x] | [x] | [x] | [ ] | [ ] |
| Rails 5.1 | [x] | [x] | [x] | [ ] | [ ] |
| Rails 5.2 | [x] | [x] | [x] | [ ] | [ ] |
| Rails 6.0 | [ ] | [ ] | [x] | [x] | [ ] |
| Rails 6.1 | [ ] | [ ] | [ ] | [x] | [x] |
| Rails 7.0 | [ ] | [ ] | [ ] | [ ] | [x] |
| Rails 7.1 | [ ] | [ ] | [ ] | [ ] | [ ] |
| Rails 7.2 | [ ] | [ ] | [ ] | [ ] | [ ] |


## Installation

Expand Down
5 changes: 3 additions & 2 deletions knockoff.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ Gem::Specification.new do |spec|
spec.homepage = "https://github.com/sgringwe/knockoff"
spec.license = "MIT"

spec.required_ruby_version = '>= 2.7.0'
spec.platform = Gem::Platform::RUBY
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
spec.bindir = "bin"
spec.require_paths = ["lib"]

spec.add_runtime_dependency 'activerecord', '>= 6', '< 7'
spec.add_runtime_dependency 'activesupport', '>= 6', '< 7'
spec.add_runtime_dependency 'activerecord', '>= 6.1', "< 7.1"
spec.add_runtime_dependency 'activesupport', '>= 6.1', "< 7.1"

spec.add_development_dependency "bundler"
spec.add_development_dependency "rake", "~> 10.0"
Expand Down
2 changes: 1 addition & 1 deletion lib/knockoff/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def decide_with(target, check_transaction)
end

def inside_transaction?
open_transactions = run_on(:primary) { ActiveRecord::Base.connection.open_transactions }
open_transactions = run_on(:primary) { ::ActiveRecord::Base.connection.open_transactions }
open_transactions > Knockoff.base_transaction_depth
end

Expand Down
68 changes: 34 additions & 34 deletions lib/knockoff/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ class Config
attr_reader :replica_configs

# A hash of replica configs to their config hash.
attr_reader :replicas_configurations
attr_reader :replicas_configuration_hash

def initialize
@environment = 'development'
@replicas_configurations = {}
@replicas_configuration_hash = {}
set_replica_configs

if !properly_configured? && Knockoff.enabled
Expand All @@ -21,8 +21,28 @@ def initialize
end
end

def replica_database_keys
@replicas_configurations.keys
def set_replica_configs
@replica_configs ||= parse_knockoff_replica_envs_to_configs
end

def parse_knockoff_replica_envs_to_configs
# As a basic prevention of crashes, attempt to parse each DB uri
# and don't add the uri to the final list if it can't be parsed
replica_env_keys.map.with_index(0) do |env_key, index|
begin

# Configure parameters such as prepared_statements, pool, reaping_frequency for all replicas.
to_copy = ActiveRecord::Base.configurations.configs_for(env_name: 'knockoff_replicas')&.first&.configuration_hash || {}
register_replica_copy(index, env_key, to_copy)

rescue URI::InvalidURIError
Rails.logger.info "LOG NOTIFIER: Invalid URL specified in follower_env_keys. Not including URI, which may result in no followers used." # URI is purposely not printed to logs
# Return a 'nil' which will be removed from
# configs with `compact`, resulting in no configs and no followers,
# therefore disabled since this env will not be in environments list.
nil
end
end.compact
end

def replica_env_keys
Expand All @@ -35,10 +55,10 @@ def replica_env_keys

def update_replica_configs(new_configs)
if ActiveRecord::Base.configurations.configs_for(env_name: 'knockoff_replicas').present?
updated_config = new_configs.deep_dup.merge!(ActiveRecord::Base.configurations.configs_for(env_name: 'knockoff_replicas').first.config)
updated_config = new_configs.deep_dup.merge!(ActiveRecord::Base.configurations.configs_for(env_name: 'knockoff_replicas').first.configuration_hash)
end

@replicas_configurations.each do |key, _config|
@replicas_configuration_hash.each do |key, _config|
update_replica_config(key, updated_config)
end
end
Expand All @@ -50,43 +70,23 @@ def properly_configured?
!@replica_configs.empty?
end

private

def update_replica_config(key, updated_config)
merged_config = @replicas_configurations[key].config.deep_dup.merge!(updated_config)
@replicas_configurations[key] = ActiveRecord::DatabaseConfigurations::HashConfig.new(key, key, merged_config)
ActiveRecord::Base.configurations.configurations << @replicas_configurations[key]
end

def set_replica_configs
@replica_configs ||= parse_knockoff_replica_envs_to_configs
def replica_database_keys
@replicas_configuration_hash.keys
end

def parse_knockoff_replica_envs_to_configs
# As a basic prevention of crashes, attempt to parse each DB uri
# and don't add the uri to the final list if it can't be parsed
replica_env_keys.map.with_index(0) do |env_key, index|
begin

# Configure parameters such as prepared_statements, pool, reaping_frequency for all replicas.
to_copy = ActiveRecord::Base.configurations.configs_for(env_name: 'knockoff_replicas')&.first&.config || {}
register_replica_copy(index, env_key, to_copy)
private

rescue URI::InvalidURIError
Rails.logger.info "LOG NOTIFIER: Invalid URL specified in follower_env_keys. Not including URI, which may result in no followers used." # URI is purposely not printed to logs
# Return a 'nil' which will be removed from
# configs with `compact`, resulting in no configs and no followers,
# therefore disabled since this env will not be in environments list.
nil
end
end.compact
def update_replica_config(key, updated_config)
merged_config = @replicas_configuration_hash[key].configuration_hash.deep_dup.merge!(updated_config)
@replicas_configuration_hash[key] = ActiveRecord::DatabaseConfigurations::HashConfig.new(key, key, merged_config)
ActiveRecord::Base.configurations.configurations << @replicas_configuration_hash[key]
end

def register_replica_copy(index, env_key, configuration_hash)
key = "knockoff_replica_#{index}"
new_config = create_replica_copy(env_key, key, configuration_hash.deep_dup)
ActiveRecord::Base.configurations.configurations << new_config
@replicas_configurations[key] = new_config
@replicas_configuration_hash[key] = new_config
end

def create_replica_copy(env_key, key, replica_config_hash)
Expand Down
4 changes: 2 additions & 2 deletions lib/knockoff/replica_connection_pool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ def connection_class(config_key)
# TODO: Hardcoding the uri string feels meh. Either set the database config
# or reference ENV instead
Knockoff.module_eval %Q{
class #{class_name} < ActiveRecord::Base
class #{class_name} < ::ActiveRecord::Base
self.abstract_class = true
establish_connection :#{config_key}
def self.connection_db_config
configurations[#{config_key.to_s.inspect}]
configurations.find_db_config #{config_key.to_s.inspect}
end
end
}, __FILE__, __LINE__
Expand Down
2 changes: 1 addition & 1 deletion lib/knockoff/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Knockoff
VERSION = '1.4.0'.freeze
VERSION = '1.5.0'.freeze
end
2 changes: 1 addition & 1 deletion spec/knockoff_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class ActiveRecord::Relation

it 'defines self.connection_db_config' do
expect(Knockoff::KnockoffReplica0.connection_db_config).not_to be_nil
expect(Knockoff::KnockoffReplica0.connection_db_config[:adapter]).to eq 'sqlite3'
expect(Knockoff::KnockoffReplica0.connection_db_config.adapter).to eq 'sqlite3'
end

context "bad configurations" do
Expand Down

0 comments on commit bd1cfdf

Please sign in to comment.