-
Notifications
You must be signed in to change notification settings - Fork 159
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.1, drop Ruby 2.x and Rails < 6.1 #243
Support Rails 7.1, drop Ruby 2.x and Rails < 6.1 #243
Conversation
ab48304
to
ccaa208
Compare
# switches to the same tenant as before the connection switching. This problem is more evident when | ||
# using read replica in Rails 6 | ||
module ConnectionHandling | ||
def connected_to_with_tenant(role: nil, prevent_writes: false, &blk) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this method should be implemented as such:
def connected_to_with_tenant(role: nil, shard: nil, prevent_writes: false, &blk)
current_tenant = Apartment::Tenant.current
connected_to_without_tenant(role: role, shard: shard, prevent_writes: prevent_writes) do
Apartment::Tenant.switch!(current_tenant)
yield(blk)
end
end
alias connected_to_without_tenant connected_to
alias connected_to connected_to_with_tenant
Potentially current_tenant = Apartment::Tenant.current
is redundant because adapter is stored on thread and current
is delegated to the adapter so this could potentially be further simplified but needs testing (I only tested with pg).
I’m pretty new to the source code of this gem and am still struggling to understand some of the code here.
From my initial research into this monkey-patch, current rails’ connected_to
is defined as def connected_to(role: nil, shard: nil, prevent_writes: false, &blk)
- so this monkeypatch removes the ability to pass shard
and forces connected_to to always default to “nil”
I tested this with my local app with sharding and seems to work, this code doesn't seem to be tested very well, removing this monkey-patch doesn't really break tests - I believe this is because there is only 1 shard setup in test and rails caches connections and looks them up by role/shard.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing this method would be out of the scope of my PR, which is just to get Rails 7.1 supported. The only reason there's changes in this file is I got rid of the if
condition which affected the indentation of the rest of the file
c773806
to
dcb003f
Compare
dcb003f
to
76d7746
Compare
class SchemaMigration # :nodoc: | ||
class << self | ||
def table_exists? | ||
connection.table_exists?(table_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this monkey-patch needs to be removed as it breaks rails 7.1 support
This is basically an implementation of table_exists?
from rails 5.2 and has worked for rails < 7.1 because SchemaMigration
was inheriting from ActiveRecord::Base
that was implementing connection
method, after your PR, this method will start raising error "undefined local variable or method `connection' for ActiveRecord::SchemaMigration:Class"
Current implementation of table_exists is here:
def table_exists?
@pool.with_connection do |connection|
connection.data_source_exists?(table_name)
end
end
it's almost identical - the main difference is that it uses data_source_exists?
on connection while this monkey patch is forcing it to use table_exists?
The difference between these 2 methods is here:
# Checks to see if the data source +name+ exists on the database.
#
# data_source_exists?(:ebooks)
#
def data_source_exists?(name)
query_values(data_source_sql(name), "SCHEMA").any? if name.present?
rescue NotImplementedError
data_sources.include?(name.to_s)
end
# Checks to see if the table +table_name+ exists on the database.
#
# table_exists?(:developers)
#
def table_exists?(table_name)
query_values(data_source_sql(table_name, type: "BASE TABLE"), "SCHEMA").any? if table_name.present?
rescue NotImplementedError
tables.include?(table_name.to_s)
end
so basically just data_source_sql(name)
VS data_source_sql(table_name, type: "BASE TABLE")
, the difference that this type:
part does, is that on table_exists it only looks up partitioned tables and relational tables, and on data_source_exists it also looks up views and materialised views, so this difference is irrelevant for schema migrations.
I believe this monkey-patch needs to be removed, this will 100% cause errors on rails 7.1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a failing test I can add then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling ActiveRecord::SchemaMigration.table_exists?
should be enough,
In rails 7.1 it should raise undefined local variable or method 'connection' for ActiveRecord::SchemaMigration:Class (NameError)
In rails 7.0 it should be perfectly fine and return true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this was added because table_exists?
was removed from SchemaMigration in rails 6.1, but it looks like it was added back in 7.0. Also, you're looking at main
in Rails. you need to look at the 7.1 branch. As far as I can tell, this monkey patch is fine, as it is identical to the method in 7.0 and 7.1, and fixes the issue in 6.1. You're right that when 7.2 comes out that this will need to be changed again or just dropped entirely since 6.0 will go out of support at that point, but it seems fine now
We had issues with Rails 7.1 and the postgresql adapter, causing a lot of very heavy internal queries, which we reported to rails/rails but which was closed as an Apartment issue (rails/rails#49976) Curious, does this PR resolve this? |
@JakubF any idea of when this can get merged? This is currently a blocker for upgrading my app to 7.1.3, and really would like to avoid forking. |
@riggleg maybe? |
@Amnesthesia I haven't had a chance to look at the issue you linked to yet, just FYI |
Alright, thanks for the update! |
@Amnesthesia Hi, I'm a new maintainer! Taking a look at the issue you reported to Rails, my understanding is that Rails 7.1 adds the ability to set the isolation level using Fibers to be Fiber-safe, whereas before, the focus was on Threads. Threads are still the default for Rails 7.1.
|
POSTGRES_HOST_AUTH_METHOD: "trust" | ||
- image: mysql:5.7 | ||
- image: cimg/<< parameters.ruby_version >> | ||
- image: cimg/postgres:12.13 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- image: cimg/postgres:12.13 | |
- image: cimg/postgres:12.18 |
gemfile: "gemfiles/rails_5_2.gemfile" | ||
- ruby_version: "ruby:3.2-buster" | ||
gemfile: "gemfiles/rails_5_2.gemfile" | ||
ruby_version: ["ruby:3.1.4", "ruby:3.2.2"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ruby_version: ["ruby:3.1.4", "ruby:3.2.2"] | |
ruby_version: ["ruby:3.1.4", "ruby:3.2.3"] |
UPDATE: I missed that Rails 7.1 just adds a warning about the change, so this isn't a blocker on this PR. We can address the warning in another PR. @eraffel-MDSol from PR #236 it looks like there was an API change to ActiveSupport::LobSubscriber that we should also account for in lib/apartment/log_subscriber.rb for Rails 7.1 |
@Amnesthesia I wonder if what you were experiencing might be related to this issue and have been aggravated by this change in Rails 7.1. This fix was proposed, but I wonder if it'd be better to have something like what Rails is doing for ActiveSupport::IsolatedExecutionState is better that allows use of Fibers or Threads. This could be related to the Rails 7.1 upgrade and could warrant including (unless the change is too big), but it'd be helpful if you could also test in your environment |
@mnovelo is this pr not stable enough to merge? Currently there is No 7.1 support and it appears all critical issues have been addressed. Some co-workers of mine are also looking to open a PR for Trilogy db adapter and waiting on this to merge before doing so. |
@brosintoski you're right. I just realized the logger API change is handled in Rails 7.1 with a warning, which we can address in another PR. The issue with threads vs fibers requires more investigation, so I'll merge this in for now to unblock other PRs |
@mnovelo @eraffel-MDSol thanks!!! |
It sounds very likely that it would be related to this indeed. We're in the process of getting rid of Apartment instead because of the amount of headache it causes us, so I'm not sure how much time I'll be able to spend on testing this |
@Amnesthesia out of curiosity what are you replacing Apartment with? |
seems like this was merged before I had a chance to read comments from the last few days |
Looking at replacing it with |
@Amnesthesia let us know how it goes! Because of how our security documentation is written, column-based multitenancy isn't an option for us, but having an "escape hatch" would be nice to document since I've seen it come up in a few issues |
@mnovelo We have still not been able to move away from Apartment. Just wondering, was the issue I brought up fixed upstream or has anybody else had issues with it? |
@Amnesthesia to my knowledge, no one else has struggled with Fibers. Better Fiber support will be included in the next release which I hope to complete soon |
No description provided.