Skip to content

Commit

Permalink
Fix memory leak in forms framework (#3266)
Browse files Browse the repository at this point in the history
  • Loading branch information
camertron authored Jan 13, 2025
1 parent 87b0ddb commit 73d64d9
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .changeset/tall-cats-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/view-components': patch
---

Fix memory leak in forms framework causing form templates to be compiled on each render in development
49 changes: 32 additions & 17 deletions app/lib/primer/forms/acts_as_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,30 +66,45 @@ def compile!
@compiled = true
end

private

def template_root_path
return @template_root_path if defined?(@template_root_path)

form_path = Utils.const_source_location(self.name)
@template_root_path = if form_path
File.join(File.dirname(form_path), self.name.demodulize.underscore)
@template_root_path =
if form_path
File.join(File.dirname(form_path), self.name.demodulize.underscore)
end
end

def base_template_path
return @base_template_path if defined?(@base_path)
base_path = Utils.const_source_location(self.name)

if base_path
@base_template_path = File.dirname(base_path)
else
warn "Could not identify the template for #{self}"
end
end

private

def template_globs
@template_globs ||= []
end

def compile_templates_in(template_glob)
pattern = if Pathname(template_glob.glob_pattern).absolute?
template_glob.glob_pattern
else
# skip compilation for anonymous form classes, as in tests
return unless template_root_path

File.join(template_root_path, template_glob.glob_pattern)
end
pattern = template_glob.glob_pattern
pattern = pattern.gsub("%{base_template_path}", base_template_path) if base_template_path
pattern =
if Pathname(pattern).absolute?
pattern
else
# skip compilation for anonymous form classes, as in tests
return unless template_root_path

File.join(template_root_path, pattern)
end

template_paths = Dir.glob(pattern)

Expand Down Expand Up @@ -117,11 +132,11 @@ def compile_template(path)
handler = ActionView::Template.handler_for_extension("erb")
template = File.read(path)
template_params = TemplateParams.new({
source: template,
identifier: __FILE__,
type: "text/html",
format: "text/html"
})
source: template,
identifier: __FILE__,
type: "text/html",
format: "text/html"
})

# change @output_buffer ivar to output_buffer method call
BufferRewriter.rewrite(
Expand Down
17 changes: 5 additions & 12 deletions app/lib/primer/forms/base_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,11 @@ class BaseComponent
include Primer::ClassNameHelper
extend ActsAsComponent

def self.compile!
base_path = Utils.const_source_location(self.name)

unless base_path
warn "Could not identify the template for #{base}"
return
end

dir = File.dirname(base_path)
renders_template File.join(dir, "#{self.name.demodulize.underscore}.html.erb"), :render_template

super
def self.inherited(base)
base.renders_template(
File.join("%{base_template_path}", "#{base.name.demodulize.underscore}.html.erb"),
:render_template
)
end

delegate :required?, :disabled?, :hidden?, to: :@input
Expand Down

0 comments on commit 73d64d9

Please sign in to comment.