Open elado opened 9 years ago
I could ask if Handlebars::Context.current
has a value and recompile another template. Not optimal though.
+1 Just rolled this out and we're seeing Maximum call stack size exceeded. Using a shared context across multiple threads in puma/Rails.
@elado I was able to reproduce using your code, but I had to increase the number of "times" significantly to get it to reproduce the issue in a console.
For example, this code reproduces consistently (whereas yours was not):
require 'celluloid'
handlebars = Handlebars::Context.new
tpl = handlebars.compile('Test {{test}}')
# works fine
100.times { 20.times.map { |i| Celluloid::Future.new { puts "start #{i}"; sleep 0.1; puts "end #{i}" } }.each(&:value) }
# process will hang forever at some point
100.times { 20.times.map { |i| Celluloid::Future.new { puts "start #{i}"; tpl.call(test: 123); puts "end #{i}" } }.each(&:value) }
I thought that perhaps the handlebars context was not threadsafe. So I tried creating a new handlebars context for each thread. This also seems to completely lock up the process.
Here is a test case that reproduces for me. @elado can you confirm this reproduces for you too?
require 'celluloid'
100.times { 20.times.map { |i| Celluloid::Future.new { puts "start #{i}"; Handlebars::Context.new.compile("Test {{test}}").call(test: 123); puts "end #{i}" } }.each(&:value) }
Any known workarounds here? This is a critical production issue for us.
@jeremyhaile https://github.com/cowboyd/handlebars.rb/blob/master/lib/handlebars/template.rb the context is being saved globally, I believe that's the issue.
I ended up migrating to ERB. With compiled ERB, performance was pretty good anyway.
@elado yeah, I switched to liquid.
I am experiencing this issue as well, I have my ruby gem called monster-queries where I used handlebars to intermix SQL queries together. It only became an evident problem when using puma a new version of Rails and Ruby. I might have to migrate away from handlebar unless I successful doing some deep digging on this issue.
I'm considering moving over to https://github.com/jamesotron/FlavourSaver or Liquid templates
Looks like rending same compiled template many times simultaneously fires errors like
V8::Error: Maximum call stack size exceeded
or worse, gets the process stuck.Is there a better practice for that? I don't want to lose the speed of compiled templates.
The rendering is running under Sidekiq process which gets stuck often.