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

Feature query annotation #54

Merged
merged 18 commits into from
Jan 26, 2024
Merged

Feature query annotation #54

merged 18 commits into from
Jan 26, 2024

Conversation

helpotters
Copy link
Collaborator

@helpotters helpotters commented Dec 13, 2023

  • annotate queries that pass through Readyset.route
  • tagged with /*routed_to_readyset?:true*/

The feature below is made redundant by having query_logs_enabled set to true.

  • toggle this feature on using config.query_annotations = true

@helpotters helpotters added the enhancement New feature or request label Dec 13, 2023
@helpotters helpotters added this to the Milestone 1 milestone Dec 13, 2023
@helpotters helpotters self-assigned this Dec 13, 2023
@helpotters helpotters linked an issue Dec 13, 2023 that may be closed by this pull request
@helpotters helpotters changed the base branch from main to add-route-and-exclude December 13, 2023 09:04
Base automatically changed from add-route-and-exclude to main December 13, 2023 22:54
@helpotters
Copy link
Collaborator Author

I'm sharing the failing code. I'm having a major difficulty with the testing environment setup with enabling QueryLogs. By default, it should at least add /*application:MyApp*/ to every query in test.log.

class_methods do
def route(prevent_writes: true, &block)
if Readyset.configuration.query_annotations
ActiveSupport::ExecutionContext.set(readyset_query: 'routed_to_readyset')
Copy link
Contributor

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

Copy link
Collaborator Author

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.

Copy link
Contributor

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

Copy link
Collaborator Author

@helpotters helpotters Dec 19, 2023

Choose a reason for hiding this comment

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

Yesterday it wasn't printing /*application:Combustion*/ in test.log queries, but it is today!
image

(╯°□°)╯︵ ┻━┻

@helpotters helpotters marked this pull request as ready for review December 19, 2023 23:21
Copy link
Contributor

@ethan-readyset ethan-readyset left a 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

spec/ready_set_spec.rb Show resolved Hide resolved
spec/configuration_spec.rb Outdated Show resolved Hide resolved
lib/readyset.rb Outdated Show resolved Hide resolved
Copy link
Contributor

@ethan-readyset ethan-readyset left a 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

lib/readyset/railtie.rb Outdated Show resolved Hide resolved
spec/configuration_spec.rb Outdated Show resolved Hide resolved
spec/railtie_spec.rb Outdated Show resolved Hide resolved
@helpotters
Copy link
Collaborator Author

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 config.after_initialize as opposed to alternatives.

lib/readyset.rb Outdated Show resolved Hide resolved
@helpotters helpotters force-pushed the feature-query-annotation branch 3 times, most recently from 1fa9d4b to 9bd36bf Compare January 23, 2024 14:42
@helpotters
Copy link
Collaborator Author

That was a rough rebase, but now a spec isn't passing anymore :((. Gotta figure it out.

@ethan-readyset
Copy link
Contributor

@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

@ethan-readyset
Copy link
Contributor

@helpotters Fixed in #72

@helpotters
Copy link
Collaborator Author

🎶 This is ready for another go 🎶

@ethan-readyset
Copy link
Contributor

@helpotters Looks great! Ready to merge after a rebase to resolve the merge conflict

ethowitz and others added 4 commits January 26, 2024 14:12
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.
helpotters and others added 10 commits January 26, 2024 14:12
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`.
@ethan-readyset ethan-readyset added this pull request to the merge queue Jan 26, 2024
Merged via the queue into main with commit 3306f16 Jan 26, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add ability to annotate the queries that are routed to ReadySet
3 participants