Module: Axn::Extras::Strategies::Vernier
- Defined in:
- lib/axn/extras/strategies/vernier.rb
Class Method Summary collapse
-
.configure(if: nil, sample_rate: 0.1, output_dir: nil) ⇒ Module
A configured module that adds profiling to the action.
Class Method Details
.configure(if: nil, sample_rate: 0.1, output_dir: nil) ⇒ Module
Returns A configured module that adds profiling to the action.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/axn/extras/strategies/vernier.rb', line 14 def self.configure(if: nil, sample_rate: 0.1, output_dir: nil) condition = binding.local_variable_get(:if) sample_rate_value = sample_rate output_dir_value = output_dir || _default_output_dir Module.new do extend ActiveSupport::Concern included do class_attribute :_vernier_condition, default: condition class_attribute :_vernier_sample_rate, default: sample_rate_value class_attribute :_vernier_output_dir, default: output_dir_value around do |hooked| _with_vernier_profiling { hooked.call } end end private def _with_vernier_profiling(&) return yield unless _should_profile? _profile_with_vernier(&) end def _profile_with_vernier(&) _ensure_vernier_available! class_name = self.class.name.presence || "AnonymousAction" profile_name = "axn_#{class_name}_#{Time.now.to_i}" # Ensure output directory exists (only once per instance) _ensure_output_directory_exists # Build output file path output_dir = self.class._vernier_output_dir || _default_output_dir output_file = File.join(output_dir, "#{profile_name}.json") # Configure Vernier with our settings = { out: output_file, allocation_sample_rate: (self.class._vernier_sample_rate * 1000).to_i, } ::Vernier.profile(**, &) end def _ensure_output_directory_exists return if @_vernier_directory_created output_dir = self.class._vernier_output_dir || _default_output_dir FileUtils.mkdir_p(output_dir) @_vernier_directory_created = true end def _should_profile? # Fast path: no condition means always profile return true unless self.class._vernier_condition # Slow path: evaluate condition (only when needed) Axn::Core::Flow::Handlers::Invoker.call( action: self, handler: self.class._vernier_condition, operation: "determining if profiling should run", ) end def _ensure_vernier_available! return if defined?(::Vernier) && ::Vernier.is_a?(Module) begin require "vernier" rescue LoadError raise LoadError, <<~ERROR Vernier profiler is not available. To use profiling, add 'vernier' to your Gemfile: gem 'vernier', '~> 1.0' Then run: bundle install ERROR end end def _default_output_dir if defined?(Rails) && Rails.respond_to?(:root) Rails.root.join("tmp", "profiles") else Pathname.new("tmp/profiles") end end end end |