-
Notifications
You must be signed in to change notification settings - Fork 1
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
Feature query annotation #54
Conversation
d422aea
to
23a04ac
Compare
I'm sharing the failing code. I'm having a major difficulty with the testing environment setup with enabling |
lib/readyset/query_annotator.rb
Outdated
class_methods do | ||
def route(prevent_writes: true, &block) | ||
if Readyset.configuration.query_annotations | ||
ActiveSupport::ExecutionContext.set(readyset_query: 'routed_to_readyset') |
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.
Hmm ActiveSupport::ExecutionContext
is an undocumented class in Rails, so we probably shouldn't use it here -- it could be changed/removed with minor Rails version updates.
I think we can integrate the way that the ActiveRecord::QueryLogs
documentation suggests: api.rubyonrails.org/classes/ActiveSupport/QueryLogs.html
New comment tags can be defined by adding them in a Hash to the tags Array. Tags can have dynamic content by setting a Proc or lambda value in the Hash, and can reference any value stored by Rails in the context object. ActiveSupport::CurrentAttributes can be used to store application values. Tags with nil values are omitted from the query comment.
Basically, we could do something like this to pass info about whether we're routing to ReadySet:
Rails.configuration.active_record.query_log_tags << {
routed_to_readyset?: ->(context) do
Current.routing_to_readyset?
end,
}
Where Current
is defined like so:
module Readyset
class Current < ActiveSupport::CurrentAttributes
attr_writer :routing_to_readyset
def routing_to_readyset?
!!@routing_to_readyset
end
end
end
Then we'd just need to update the routing_to_readyset
attribute whenever Readyset.route
is called:
def self.route(prevent_writes: true, &block)
Current.routing_to_readyset = true
...
ensure
Current.routing_to_readyset = false
end
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.
Hmm. I'm still figuring out how to check that the SQL comment was added.
So far, it's been a struggle trying to get it to output the SQL query log with comments enabled. It might be a limitation with Combustion.
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'd say we should probably switch to integrating via ActiveRecord::QueryLogs
before spending too much time debugging the specs. It's possible there's something about using ExecutionContext
that's causing the spec issue
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.
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.
Looks great! 🙌 Just a few questions/suggestions
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.
Looks great! Just a few comments
For review, I would recommend double-checking this snippet of code: initializer 'readyset.query_annotator' do |app|
setup_query_annotator
end
def setup_query_annotator
config.after_initialize do
...
end
end I'm a bit unsure about the usage of |
1fa9d4b
to
9bd36bf
Compare
That was a rough rebase, but now a spec isn't passing anymore :((. Gotta figure it out. |
@helpotters Apologies for rough rebase -- I merged a bunch of big changes to main over the past week or two! The failing spec is my fault -- I can spend some time digging into this later today |
@helpotters Fixed in #72 |
9bd36bf
to
497f2f5
Compare
🎶 This is ready for another go 🎶 |
@helpotters Looks great! Ready to merge after a rebase to resolve the merge conflict |
This commit adds two methods to `ActiveRecord::Relation`: - `Relation#create_readyset_cache!`, which creates a new cache based on the query represented by the relation; and - `Relation#drop_cache!`, which drops the cache associated with the query represented by the relation (if one exists)
Adds a `Readyset.route` method, which takes a block and routes to ReadySet all the queries that occur within that block.
Users can enable :query_annotations in the initializer file.
This is merely to share the failing spec.
This feature will provide a context object to QueryLogs. It will require configuration by passing the QueryAnnotator method as context. ``` config.active_record.query_log_tags << { routed_to_readyset?: ->(context) do Readyset::QueryAnnotator.routing_to_readyset? end, } ```
This loads in the `routing_to_readyset?` context to the query tag logs list in the Rails app. Currently having difficulties handling the initializer order with the Combustion application running.
`.route` toggles the query annotation context to true and turns it off regardless of how `.route` returns. Just adding spec coverage for this.
Query log tags will be enabled by default on development environments for the convenience of the user.
Previous implementation conflicted with the usage of a nested `connected_to` in `.route`. This new implementation just defines the query tag in the railtie initializer instead. It also uses `destination` with the values of `primary` and `readyset`.
497f2f5
to
a181175
Compare
Readyset.route
/*routed_to_readyset?:true*/
The feature below is made redundant by having
query_logs_enabled
set totrue
.toggle this feature on usingconfig.query_annotations = true