Templates that use `assign` / `capture` tags are thread-unsafe
UlyssesZh opened this issue · comments
Ulysses Zhan commented
require 'liquid'
Liquid::Template.register_filter Module.new { def s(input) = sleep(input/10.0) && input }
template = Liquid::Template.parse '{% assign u = v %}{{ u | s }}{{ u }}'
3.times.map { |i| Thread.new { print template.render! 'v' => i } }.each &:join
Expected output: 001122
; Actual output: 021222
.
Why I found this: jekyll/jekyll#9485 (comment)
Alberto Roura commented
This actually would be super interesting to solve! +100000
Ian Ker-Seymer commented
I think this happens because certain state for a Liquid::Context
will be re-used when a hash passed in to Liquid::Template#render
. If you want to avoid that behavior, it is best to explicitly create a new Liquid::Context
for each render invocation, i.e.:
template.render!(Liquid::Context.new("v" => i))