Browse Source

action_view memoize partials

main
pvincent 2 months ago
parent
commit
18fe5b6f7f
  1. 5
      config/initializers/backtrace_cleaning.rb
  2. 23
      lib/semantic/abstract_formatter.rb
  3. 26
      lib/semantic/helper.rb
  4. 43
      lib/semantic/subscribers/action_view.rb

5
config/initializers/backtrace_cleaning.rb

@ -1,3 +1,2 @@
bc = Rails.backtrace_cleaner
# bc.add_silencer { |line| %r{^lib/(monkey_patches|semantic)}.match?(line) }
bc.add_silencer { |line| %r{^lib/(monkey_patches)}.match?(line) }
Rails.backtrace_cleaner
.add_silencer { |line| %r{^lib/(monkey_patches)}.match?(line) }

23
lib/semantic/abstract_formatter.rb

@ -28,11 +28,9 @@ module Semantic
clazz = colorize("#{exc.class}\n", color_map[:fatal]) clazz = colorize("#{exc.class}\n", color_map[:fatal])
message = colorize(exc.message.chomp(''), color_map[:error]) message = colorize(exc.message.chomp(''), color_map[:error])
# TODO: backtrace_cleaner might be optionally disable from Live::Constant
backtrace = stackisize(Rails.backtrace_cleaner.clean(exc.backtrace))
"#{clazz}#{message}#{backtrace}"
backtrace = exc.backtrace
stack = Helper.stackisize(*backtrace)
["#{clazz}#{message}", stack].compact.join("\n")
end end
def origin def origin
@ -41,21 +39,6 @@ module Semantic
colorize(centerize(log.name), taint) colorize(centerize(log.name), taint)
end end
def ansi_trace(trace, symbol)
match = trace.match(/(↳ )?(.*:\d+)(:in `)?(.*'?)/) # only m2(=file) and m4(=optional function) are useful
return trace unless match
_, m2, _, m4 = match.captures
"#{symbol} #{m2} #{BOLD}#{m4.chop}#{CLEAR}"
end
def stackisize(items)
return '' if items.empty?
traces = items.map { |item| ansi_trace(item, '➟') }
"\n#{traces.join("\n")}"
end
def tags def tags
first_tag, taint = log.tags.empty? ? [TAG_NONE, CLEAR] : [log.tags.first, BG_GRAY + TEXT_YELLOW] first_tag, taint = log.tags.empty? ? [TAG_NONE, CLEAR] : [log.tags.first, BG_GRAY + TEXT_YELLOW]
colorize(centerize(first_tag, TAG_FIXED_LENGTH), taint) colorize(centerize(first_tag, TAG_FIXED_LENGTH), taint)

26
lib/semantic/helper.rb

@ -0,0 +1,26 @@
module Semantic
# useful public functions
module Helper
class << self
include AnsiColors
def stackisize(*items)
return if items.empty?
Rails.backtrace_cleaner
.clean(items)
.map { |item| ansi_trace(item, '➟') }
.join("\n")
end
private
def ansi_trace(trace, symbol)
match = trace.match(/(↳ )?(.*:\d+)(:in `)?(.*'?)/) # only m2(=file) and m4(=optional function) are useful
return trace unless match
_, m2, _, m4 = match.captures
"#{symbol} #{m2} #{BOLD}#{m4.chop}#{CLEAR}"
end
end
end
end

43
lib/semantic/subscribers/action_view.rb

@ -6,12 +6,19 @@ module Semantic
REGEX_BASEDIR = %r{^#{Rails.root}/(.*)} REGEX_BASEDIR = %r{^#{Rails.root}/(.*)}
def initialize(*) = super(:view)
def initialize(*)
super(:view)
@partials = {}
end
def render_partial(event) def render_partial(event)
identifier = pathname(event.payload[:identifier]) identifier = pathname(event.payload[:identifier])
# logger.debug("Rendered partial #{identifier}", event.payload[:locals]) if identifier
logger.debug("Rendered partial #{identifier}") if identifier
partial_savings = @partials[event.transaction_id] ||= {}
partial_saving = partial_savings[identifier] ||= {
count: 0,
first_origin: Rails.backtrace_cleaner.clean(caller)[1]
}
partial_saving[:count] += 1
end end
def render_template(event) def render_template(event)
@ -19,23 +26,47 @@ module Semantic
return unless layout return unless layout
identifier = pathname(event.payload[:identifier]) identifier = pathname(event.payload[:identifier])
logger.debug { "Rendered template #{identifier}" } if identifier
return unless identifier
logger.debug do
pop_partial_savings(event.transaction_id)
"Rendered template #{identifier}"
end
end end
def render_collection(event) def render_collection(event)
identifier = pathname(event.payload[:identifier]) identifier = pathname(event.payload[:identifier])
return unless identifier
count = event.payload[:count] count = event.payload[:count]
cache_hits = event.payload[:cache_hits] || 0 cache_hits = event.payload[:cache_hits] || 0
logger.debug { "Rendered collection #{identifier} (#{count} times, #{cache_hits} cached)" } if identifier
logger.debug do
pop_partial_savings(event.transaction_id)
"Rendered collection #{identifier} (#{count} times, #{cache_hits} cached)"
end
end end
def render_layout(event) def render_layout(event)
identifier = pathname(event.payload[:identifier]) identifier = pathname(event.payload[:identifier])
logger.debug { "Rendered layout #{identifier}" } if identifier
return unless identifier
logger.debug do
pop_partial_savings(event.transaction_id)
"Rendered layout #{identifier}"
end
end end
private private
def pop_partial_savings(transaction_id)
partial_savings = @partials.delete(transaction_id)
partial_savings.each do |partial, saving|
count_info = " (#{saving[:count]} times)" if saving[:count] > 1
logger.debug("Rendered partial #{partial}#{count_info}")
logger.debug(Semantic::Helper.stackisize(saving[:first_origin]))
end
end
def pathname(location) def pathname(location)
m = REGEX_BASEDIR.match(location) m = REGEX_BASEDIR.match(location)
m[1] if m m[1] if m

Loading…
Cancel
Save