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

Monkey patching not working #3570

Open
n-rodriguez opened this issue May 13, 2024 · 1 comment
Open

Monkey patching not working #3570

n-rodriguez opened this issue May 13, 2024 · 1 comment

Comments

@n-rodriguez
Copy link

n-rodriguez commented May 13, 2024

Hi there!

I'm trying to run a Rails application with TruffleRuby 24.0.1 and it almost works expect one thing : a monkey patch is not applied to the codebase :/

The patch :

# frozen_string_literal: true

# Add queries count to template rendering instrumentation
# See: https://github.com/rails/rails/pull/51457

# return if Settings.java_ruby?

require 'active_record/railties/controller_runtime'
require 'active_record/runtime_registry'

module Concerto
  module CoreExt
    module RailsPatch
      module ControllerRuntimePatch
        module ClassMethods
          def log_process_action(payload)
            messages, db_runtime = super, payload[:db_runtime]

            if db_runtime
              queries_count = payload[:queries_count] || 0
              cached_queries_count = payload[:cached_queries_count] || 0
              messages << ("ActiveRecord: %.1fms (%d %s, %d cached)" % [db_runtime.to_f, queries_count,
                                                                        "query".pluralize(queries_count), cached_queries_count])
            end

            messages
          end
        end
        module InstanceMethods
          private

            def cleanup_view_runtime
              if logger && logger.info?
                db_rt_before_render = ActiveRecord::RuntimeRegistry.reset_runtimes
                self.db_runtime = (db_runtime || 0) + db_rt_before_render
                runtime = super
                queries_rt = ActiveRecord::RuntimeRegistry.sql_runtime - ActiveRecord::RuntimeRegistry.async_sql_runtime
                db_rt_after_render = ActiveRecord::RuntimeRegistry.reset_runtimes
                self.db_runtime += db_rt_after_render
                runtime - queries_rt
              else
                super
              end
            end

            def append_info_to_payload(payload)
              super

              payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::RuntimeRegistry.reset_runtimes
              payload[:queries_count] = ActiveRecord::RuntimeRegistry.reset_queries_count
              payload[:cached_queries_count] = ActiveRecord::RuntimeRegistry.reset_cached_queries_count
            end
        end
      end

      module ActiveRecordPatch
        def queries_count
          ActiveSupport::IsolatedExecutionState[:active_record_queries_count] ||= 0
        end

        def queries_count=(count)
          ActiveSupport::IsolatedExecutionState[:active_record_queries_count] = count
        end

        def cached_queries_count
          ActiveSupport::IsolatedExecutionState[:active_record_cached_queries_count] ||= 0
        end

        def cached_queries_count=(count)
          ActiveSupport::IsolatedExecutionState[:active_record_cached_queries_count] = count
        end

        def reset
          reset_runtimes
          reset_queries_count
          reset_cached_queries_count
        end

        def reset_runtimes
          rt, self.sql_runtime = sql_runtime, 0.0
          self.async_sql_runtime = 0.0
          rt
        end

        def reset_queries_count
          qc = queries_count
          self.queries_count = 0
          qc
        end

        def reset_cached_queries_count
          qc = cached_queries_count
          self.cached_queries_count = 0
          qc
        end
      end
    end
  end
end

ActiveRecord::Railties::ControllerRuntime::ClassMethods.prepend(Concerto::CoreExt::RailsPatch::ControllerRuntimePatch::ClassMethods)
ActiveRecord::Railties::ControllerRuntime.prepend(Concerto::CoreExt::RailsPatch::ControllerRuntimePatch::InstanceMethods)
ActiveRecord::RuntimeRegistry.include(Concerto::CoreExt::RailsPatch::ActiveRecordPatch)

ActiveSupport::Notifications.monotonic_subscribe("sql.active_record") do |name, start, finish, id, payload| # rubocop:disable Lint/UnusedBlockArgument,Style/StringLiterals
  unless ["SCHEMA", "TRANSACTION"].include?(payload[:name]) # rubocop:disable Style/StringLiterals,Style/WordArray
    ActiveRecord::RuntimeRegistry.queries_count += 1
    ActiveRecord::RuntimeRegistry.cached_queries_count += 1 if payload[:cached]
  end
end

This monkey patch is extracted from this PR : rails/rails#51457

The error is :

Exiting
/Users/nicolas/PROJECTS/CONCERTO/concerto/lib/concerto/core_ext/rails_patch.rb:107:in `block in <top (required)>': undefined method `queries_count' for ActiveRecord::RuntimeRegistry:Module (NoMethodError)
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:137:in `block in finish'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:26:in `block in iterate_guarding_exceptions'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:25:in `each'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:25:in `iterate_guarding_exceptions'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:125:in `each'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:136:in `finish'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:262:in `block in finish_with_values'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:26:in `block in iterate_guarding_exceptions'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:25:in `each'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:25:in `iterate_guarding_exceptions'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:261:in `finish_with_values'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/fanout.rb:254:in `finish'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/notifications/instrumenter.rb:64:in `instrument'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract_adapter.rb:1143:in `log'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql_adapter.rb:892:in `exec_no_cache'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql_adapter.rb:872:in `execute_and_clear'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:64:in `internal_exec_query'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:630:in `select'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:71:in `select_all'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/query_cache.rb:115:in `select_all'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation.rb:994:in `block (2 levels) in exec_main_query'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation/finder_methods.rb:467:in `apply_join_dependency'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation.rb:988:in `block in exec_main_query'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation.rb:1018:in `skip_query_cache_if_necessary'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation.rb:984:in `exec_main_query'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation.rb:962:in `block in exec_queries'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation.rb:1018:in `skip_query_cache_if_necessary'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation.rb:956:in `exec_queries'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation.rb:742:in `load'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation.rb:264:in `records'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activerecord-7.1.3.2/lib/active_record/relation/delegation.rb:100:in `-'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/app/models/region.rb:108:in `for_french_site'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/vendor/engines/concerto_france/config/routes.rb:54:in `block in <top (required)>'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/actionpack-7.1.3.2/lib/action_dispatch/routing/mapper.rb:636:in `instance_exec'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/actionpack-7.1.3.2/lib/action_dispatch/routing/mapper.rb:636:in `block in with_default_scope'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/actionpack-7.1.3.2/lib/action_dispatch/routing/mapper.rb:882:in `scope'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/actionpack-7.1.3.2/lib/action_dispatch/routing/mapper.rb:635:in `with_default_scope'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/actionpack-7.1.3.2/lib/action_dispatch/routing/route_set.rb:446:in `eval_block'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/actionpack-7.1.3.2/lib/action_dispatch/routing/route_set.rb:430:in `draw'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/vendor/engines/concerto_france/config/routes.rb:4:in `<top (required)>'
	from <internal:core> core/kernel.rb:378:in `load'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/application/routes_reloader.rb:50:in `block in load_paths'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/application/routes_reloader.rb:50:in `each'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/application/routes_reloader.rb:50:in `load_paths'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/application/routes_reloader.rb:24:in `reload!'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/application/routes_reloader.rb:38:in `block in updater'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/activesupport-7.1.3.2/lib/active_support/file_update_checker.rb:85:in `execute'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/application/routes_reloader.rb:13:in `execute'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/application/finisher.rb:161:in `block in <module:Finisher>'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/initializable.rb:32:in `instance_exec'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/initializable.rb:32:in `run'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/initializable.rb:61:in `block in run_initializers'
	from /Users/nicolas/.asdf/installs/ruby/truffleruby-24.0.1/lib/mri/tsort.rb:228:in `block in tsort_each'
	from /Users/nicolas/.asdf/installs/ruby/truffleruby-24.0.1/lib/mri/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
	from /Users/nicolas/.asdf/installs/ruby/truffleruby-24.0.1/lib/mri/tsort.rb:431:in `each_strongly_connected_component_from'
	from /Users/nicolas/.asdf/installs/ruby/truffleruby-24.0.1/lib/mri/tsort.rb:349:in `block in each_strongly_connected_component'
	from /Users/nicolas/.asdf/installs/ruby/truffleruby-24.0.1/lib/mri/tsort.rb:347:in `each'
	from /Users/nicolas/.asdf/installs/ruby/truffleruby-24.0.1/lib/mri/tsort.rb:347:in `each_strongly_connected_component'
	from /Users/nicolas/.asdf/installs/ruby/truffleruby-24.0.1/lib/mri/tsort.rb:226:in `tsort_each'
	from /Users/nicolas/.asdf/installs/ruby/truffleruby-24.0.1/lib/mri/tsort.rb:205:in `tsort_each'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/initializable.rb:60:in `run_initializers'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/application.rb:426:in `initialize!'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/config/environment.rb:7:in `<top (required)>'
	from <internal:core> core/kernel.rb:292:in `require_relative'
	from config.ru:5:in `<top (required)>'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/rack-3.0.11/lib/rack/builder.rb:103:in `new_from_string'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/rack-3.0.11/lib/rack/builder.rb:94:in `load_file'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/rack-3.0.11/lib/rack/builder.rb:64:in `parse_file'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/rackup-2.1.0/lib/rackup/server.rb:354:in `build_app_and_options_from_config'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/rackup-2.1.0/lib/rackup/server.rb:263:in `app'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/rackup-2.1.0/lib/rackup/server.rb:424:in `wrapped_app'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/commands/server/server_command.rb:76:in `log_to_stdout'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/commands/server/server_command.rb:36:in `start'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/commands/server/server_command.rb:145:in `block in perform'
	from <internal:core> core/kernel.rb:512:in `tap'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/commands/server/server_command.rb:136:in `perform'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/thor-1.3.1/lib/thor/command.rb:28:in `run'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/thor-1.3.1/lib/thor/invocation.rb:127:in `invoke_command'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/command/base.rb:178:in `invoke_command'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/thor-1.3.1/lib/thor.rb:527:in `dispatch'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/command/base.rb:73:in `perform'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/command.rb:71:in `block in invoke'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/command.rb:149:in `with_argv'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/command.rb:69:in `invoke'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/railties-7.1.3.2/lib/rails/commands.rb:18:in `<top (required)>'
	from <internal:core> core/kernel.rb:229:in `gem_original_require'
	from <internal:/Users/nicolas/.asdf/installs/ruby/truffleruby-24.0.1/lib/mri/rubygems/core_ext/kernel_require.rb>:37:in `require'
	from /Users/nicolas/PROJECTS/CONCERTO/concerto/.bundle/truffleruby/3.2.2.24.0.0.2/gems/bootsnap-1.18.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from bin/rails:4:in `<main>'

This works perfectly with Ruby 3.3.1.

Thank you!

@andrykonchin
Copy link
Member

Thank you for the report, we'll look into it.

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

No branches or pull requests

2 participants