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

Allow overriding Prosopite.raise config to temporarily raise on N+1s #44

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

DanielGilchrist
Copy link

Hello and thank you for this gem!

I'm in the process of integrating Prosopite into our Rails codebase and we're going for an incremental approach by setting Prosopite.raise = false during configuration to avoid disrupting development. The problem for us with this is we also want to be able to raise on specific actions / controllers once N+1s have been eliminated from them with an around action. We considered setting config to always raise and only setting the around action for controllers / actions with N+1s resolved but we're also really keen on keeping the logs for existing N+1s

Here's an example of it's usage in a Rails app where Prosopite.raise is set to false:

class ApplicationController < ActionController::Base
  ...

  def self.raise_on_n_plus_ones!(**options)
    return unless Rails.configuration.x.prosopite.enabled?

    prepend_around_action(:_raise_on_n_plus_ones, **options)
  end

  if Rails.configuration.x.prosopite.enabled?
    around_action :n_plus_one_detection

    def n_plus_one_detection
      Prosopite.scan
      yield
    ensure
      Prosopite.finish
    end

    def _raise_on_n_plus_ones
      Prosopite.force_raise
      yield
    ensure
      Prosopite.unforce_raise
    end
  end
end

class UserController < ApplicationController
  # only raises on N+1s introduced to the index action
  raise_on_n_plus_ones!(only: [:index])

  def index
    ...
  end

  def edit
    ...
  end
end

Please let me know if you'd prefer a different API or anything else and I'll fix it up, thanks!

lib/prosopite.rb Outdated Show resolved Hide resolved
Co-authored-by: Alex Ghiculescu <[email protected]>
@charkost
Copy link
Owner

charkost commented Jun 18, 2022

Hello!
Wouldn't you achieve the same by using the Prosopite.raise setter?

def _raise_on_n_plus_ones
  Prosopite.raise = true
  yield
ensure
  Prosopite.raise = false
end

The setter should probably be modified to be thread safe though.

@DanielGilchrist
Copy link
Author

Hello! Wouldn't you achieve the same by using the Prosopite.raise setter?

def _raise_on_n_plus_ones
  Prosopite.raise = true
  yield
ensure
  Prosopite.raise = false
end

The setter should probably be modified to be thread safe though.

Thank you for your response and sorry for the late reply!

The main reason is that the current implementation of Prosopite.raise doesn't work well for multi-threaded applications or between requests (in our case a Rails application) as it's an instance variable on the class itself. This works great for initial setup but could lead to confusing behaviour when set dynamically on the class

Happy to look into moving to a Prosopite.raise focused API if you think that would be more suitable

@ghiculescu
Copy link
Contributor

@charkost is there anything we can do to nudge this PR along? 🙏

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.

3 participants