Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Rails 7.0 #26

Merged
merged 18 commits into from
Jun 16, 2023
Merged

Conversation

lorint
Copy link
Collaborator

@lorint lorint commented Feb 2, 2023

Based on feedback from @bensheldon and @matthewd in #20, here is a new PR to bring support for ActiveRecord 7.0 to ARTA. Key goals:

  • Focus only on Rails 7.0
  • Change the adapter's interface/implementation using ActiveRecord version checks, and not feature detection

@lorint lorint requested a review from a team as a code owner February 2, 2023 10:34
Copy link
Contributor

@dhruvCW dhruvCW left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for doing this, and apologies for the intrusion, just figured I could leave some comments that could help speed up the process a bit 😁 👍

activerecord-trilogy-adapter.gemspec Outdated Show resolved Hide resolved
lib/active_record/connection_adapters/trilogy_adapter.rb Outdated Show resolved Hide resolved
lib/active_record/connection_adapters/trilogy_adapter.rb Outdated Show resolved Hide resolved
lib/active_record/connection_adapters/trilogy_adapter.rb Outdated Show resolved Hide resolved
lib/trilogy_adapter/errors.rb Outdated Show resolved Hide resolved
@lorint
Copy link
Collaborator Author

lorint commented Feb 9, 2023

... comments that could help speed up the process a bit 😁 👍

Thank you, Dhruv! I'll take time later this evening to implement your suggestions. I'm just one time zone away -- Nottingham, UK -- so should be updated by early tomorrow morning your time.

@dhruvCW
Copy link
Contributor

dhruvCW commented Feb 10, 2023

@lorint that looks awesome 🍻 , I think following the same thought process of splitting controversial changes into their own commits could you split code related to @verified flag out into it's own commit ?

end
end

def execute(sql, name = nil, **kwargs)
Copy link
Collaborator Author

@lorint lorint Feb 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allows this example to pass:

execute_uses_AbstractAdapter#transform_query_when_available

self
end

def reconnect!
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This in conjunction with the way reset! works allows these three examples to pass:

#reset_closes_connection_with_existing_connection
#reset_answers_new_connection_with_existing_connection
#reset_answers_new_connection_without_existing_connection

def exec_rollback_db_transaction
# 16384 tests the bit flag for SERVER_SESSION_STATE_CHANGED, which gets set when the
# last statement executed has caused a change in the server's state.
if active? || (@raw_connection.server_status & 16_384).positive?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: what is the reason for checking the server status ? IMO rollback should be a no-op if the server doesn't have any modifications right ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After careful analysis, I've found that this check for session state changed becomes useful if we were to support AR 6.1 and older, so it could be removed -- will drop in a commit for this later this evening.

(I do appreciate your interest in being thorough!)

@lorint
Copy link
Collaborator Author

lorint commented Feb 10, 2023

could you split code related to @verified flag out into it's own commit ?

Some of the key reasons that Trilogy is interesting boils down to its reliable nature under load -- specifically how it does auto-reconnects. Much of this behaviour is possible due to AR 7.1's new @verified flag, along with other related enhancements in ConnectionAdapters. This is one reason that both Github and Shopify run their environments on Edge Rails, and have worked together to make Trilogy great. If we remove @verified then it would change quite a bit of the fundamental nature of this driver, and require that a lot of test cases be skipped -- essentially everything that has to do with auto-reconnect.

To create a more "vanilla" AR 7.0 option, I would recommend a fork of this driver where all of those enhancements are removed, paring back the majority of the auto-reconnect tests. Would end up being quite a bit more trim, and likely run just fine in smaller shops -- places that don't use Percona / Vitess / etc. I could create this kind of "ARTA Lite for AR 7.0" version if that sounds interesting.

end
end

def execute(sql, name = nil, **kwargs)
Copy link
Collaborator Author

@lorint lorint Feb 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allows this example to pass:

execute_uses_AbstractAdapter#transform_query_when_available

self
end

def reconnect!
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This in conjunction with the way reset! works allows these three examples to pass:

#reset_closes_connection_with_existing_connection
#reset_answers_new_connection_with_existing_connection
#reset_answers_new_connection_without_existing_connection

@dhruvCW
Copy link
Contributor

dhruvCW commented Feb 10, 2023

Some of the key reasons that Trilogy is interesting boils down to its reliable nature under load -- specifically how it does auto-reconnects. Much of this behaviour is possible due to AR 7.1's new @verified flag, along with other related enhancements in ConnectionAdapters. This is one reason that both Github and Shopify run their environments on Edge Rails, and have worked together to make Trilogy great. If we remove @verified then it would change quite a bit of the fundamental nature of this driver, and require that a lot of test cases be skipped -- essentially everything that has to do with auto-reconnect.

Don't get me wrong I would love to keep the PR as is, I just don't want this delayed 😅 , personally the value for me also comes from the lack of dependencies and async API but the reconnection logic is indeed a massive plus.

@lorint
Copy link
Collaborator Author

lorint commented Feb 10, 2023

I just don't want this delayed

Love your zeal! Interested in having feedback from anyone willing to try this out in a QA or production environment. Anyone out there ready to put this in their Gemfile to give it a real-world spin? :)

gem 'activerecord-trilogy-adapter', git: 'https://github.com/lorint/activerecord-trilogy-adapter.git',
                                    ref: '17fba11ede4d5efdda3609af00fed85fdf5580dc'

@dhruvCW
Copy link
Contributor

dhruvCW commented Feb 10, 2023

Love your zeal! Interested in having feedback from anyone willing to try this out in a QA or production environment. Anyone out there ready to put this in their Gemfile to give it a real-world spin? :)

gem 'activerecord-trilogy-adapter', git: 'https://github.com/lorint/activerecord-trilogy-adapter.git',
                                    branch: 'support_rails_7',
                                    ref: 'd132990800ca9196b758e54f37c522a888b396fc'
                                    

so funny thing, I tried bundle exec rails db:create on a mysql 5.7 server locally with root username and an empty password and it just failed with unknown db auth error 😅

I think I am missing some steps here

@lorint
Copy link
Collaborator Author

lorint commented Feb 10, 2023

unknown db auth error

From terminal run mysql -uroot and then this, changing out cool_username and my_database:

CREATE USER cool_username@localhost IDENTIFIED BY '';
CREATE DATABASE my_database;
GRANT ALL PRIVILEGES ON my_database.* TO cool_username@localhost;
QUIT

Change the username and database name to be what you have in your database.yml, and no need to do a db:create, only db:migrate / etc. From there it's likely that all will be well 😃

@dhruvCW
Copy link
Contributor

dhruvCW commented Feb 10, 2023

From terminal run mysql -uroot and then this, changing out cool_username and my_database:

thanks but does this mean trilogy cannot be used to create a database and load a schema ?

PS: seems to only fail in db:create otherwise everything else seems to work just fine, would be interesting to know what database creation is not supported though not really a pressing issue 😁

@lorint
Copy link
Collaborator Author

lorint commented Feb 10, 2023

trilogy cannot be used to create a database

Trilogy can be used, sure -- this is more of a MySQL configuration thing we're talking about, so would recommend moving this convo to Rails discussion -- create a topic out here and we can find a solution. I'll make a quick screencast about how to configure your root user so that you can do a db:create:
https://discuss.rubyonrails.org/

@lorint lorint force-pushed the support_rails_7 branch from 4cb0096 to 38d97da Compare March 7, 2023 08:14
@lorint lorint force-pushed the support_rails_7 branch 4 times, most recently from 56a0226 to 07d70e8 Compare April 26, 2023 10:17
@lorint
Copy link
Collaborator Author

lorint commented Apr 26, 2023

@matthewd and @bensheldon -- what do you think about this commit which now converts this gem into being solely a backwards-compaible offering for Rails 7.0?

Copy link
Contributor

@bensheldon bensheldon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lorint I checked with my team and we like your suggestion of focusing this gem on versions of Rails < 7.1. I made a few suggestions for being clear on which versions those specifically are at this point in time. And let's do it!

Thank you, again, for your continued work on this 🙇🏻

CHANGELOG.md Outdated
@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

## [Unreleased]

### Added

- Support Rails 7.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably change this to be clearer of "Removed support for Rails 7.1"

@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
}

spec.add_dependency "trilogy", ">= 2.3.0"
spec.add_dependency "activerecord", "~> 7.1.a"
spec.add_dependency "activerecord", "< 7.1a"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
spec.add_dependency "activerecord", "< 7.1a"
spec.add_dependency "activerecord", ">= 7.0", "< 7.1a"

README.md Outdated
@@ -2,11 +2,13 @@

Active Record database adapter for [Trilogy](https://github.com/github/trilogy)

(This gem offers Trilogy support for versions of ActiveRecord prior to 7.1.)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(This gem offers Trilogy support for versions of ActiveRecord prior to 7.1.)
This gem offers Trilogy support for versions of ActiveRecord prior to 7.1. Currently supports:
- Rails v7.0.x

@lorint lorint force-pushed the support_rails_7 branch from ff981ba to 2c055db Compare May 5, 2023 07:07
@lorint
Copy link
Collaborator Author

lorint commented May 5, 2023

let's do it!

Yay!

Big thanks out to you and the team for all the support along the way. Thrilled that backwards-compatibility for this adapter will be available at the same time that it is formally introduced in 7.1!

@lorint lorint force-pushed the support_rails_7 branch 7 times, most recently from 812e8a2 to 87e4d02 Compare May 9, 2023 08:48
@lorint lorint force-pushed the support_rails_7 branch from 87e4d02 to 4528508 Compare May 31, 2023 21:36
@lorint lorint force-pushed the support_rails_7 branch from 4528508 to 2867e28 Compare June 1, 2023 09:06
Copy link
Contributor

@bensheldon bensheldon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reviewed this with @composerinteralia.

I am seeing 2 test failures locally, @composerinteralia is seeing one. We believe they are related to our local mysql configuration and not inherent in the library (CI is passing). To document them here:

❯ bundle exec rake
Run options: --seed 35915

# Running:

.......................E..........F........................................................

Finished in 2.922064s, 31.1424 runs/s, 57.1514 assertions/s.

  1) Error:
ActiveRecord::ConnectionAdapters::TrilogyAdapterTest#test_strict_mode_can_be_disabled:
ActiveRecord::NotNullViolation: Trilogy::ProtocolError: 1364: Field 'body' doesn't have a default value
    /Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/lib/active_record/connection_adapters/trilogy_adapter.rb:179:in `query'
    /Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/lib/active_record/connection_adapters/trilogy_adapter.rb:179:in `block (2 levels) in raw_execute'
    /Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/lib/active_record/connection_adapters/trilogy_adapter.rb:169:in `block in with_trilogy_connection'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activesupport-7.0.5/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activesupport-7.0.5/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activesupport-7.0.5/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activesupport-7.0.5/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
    /Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/lib/active_record/connection_adapters/trilogy_adapter.rb:166:in `with_trilogy_connection'
    /Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/lib/active_record/connection_adapters/trilogy_adapter.rb:177:in `block in raw_execute'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activesupport-7.0.5/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activesupport-7.0.5/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activesupport-7.0.5/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activesupport-7.0.5/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activerecord-7.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:769:in `block in log'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activesupport-7.0.5/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activerecord-7.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:760:in `log'
    /Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/lib/active_record/connection_adapters/trilogy_adapter.rb:176:in `raw_execute'
    /Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/activerecord-7.0.5/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:200:in `execute'
    /Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/lib/active_record/connection_adapters/trilogy_adapter.rb:187:in `execute'
    /Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/test/lib/active_record/connection_adapters/trilogy_adapter_test.rb:728:in `block in <class:TrilogyAdapterTest>'

  2) Failure:
ActiveRecord::ConnectionAdapters::TrilogyAdapterTest#test_.new_client_on_access_denied_error [/Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/test/lib/active_record/connection_adapters/trilogy_adapter_test.rb:44]:
[ActiveRecord::DatabaseConnectionError] exception expected, not
Class: <Trilogy::QueryError>
Message: <"trilogy_auth_recv: TRILOGY_PROTOCOL_VIOLATION">
---Backtrace---
/Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/trilogy-2.4.1/lib/trilogy.rb:174:in `_initialize'
/Users/bensheldon/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/trilogy-2.4.1/lib/trilogy.rb:174:in `initialize'
/Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/lib/active_record/connection_adapters/trilogy_adapter.rb:82:in `new'
/Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/lib/active_record/connection_adapters/trilogy_adapter.rb:82:in `new_client'
/Users/bensheldon/Repositories/github/activerecord-trilogy-adapter/test/lib/active_record/connection_adapters/trilogy_adapter_test.rb:45:in `block (2 levels) in <class:TrilogyAdapterTest>'
---------------

91 runs, 167 assertions, 1 failures, 1 errors, 0 skips
rake aborted!
Command failed with status (1)
/Users/bensheldon/.rbenv/versions/3.0.6/bin/bundle:23:in `load'
/Users/bensheldon/.rbenv/versions/3.0.6/bin/bundle:23:in `<main>'
Tasks: TOP => default => test
(See full trace by running task with --trace)

We believe this could be trilogy-libraries/trilogy#43

@bensheldon bensheldon merged commit 7976c68 into trilogy-libraries:main Jun 16, 2023
@bensheldon
Copy link
Contributor

This PR has been released: https://github.com/trilogy-libraries/activerecord-trilogy-adapter/releases/tag/v3.0.0

@lorint thank you 🎉

@lorint
Copy link
Collaborator Author

lorint commented Jun 19, 2023

This is fantastic!

If there is interest, I've put together a PR with the minor tidbits necessary to offer AR 6.1 and 6.0 support.

Looking forward to seeing many folks use Trilogy in their projects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants