wbond / pybars3

Handlebars.js template support for Python 3 and 2
GNU Lesser General Public License v3.0
179 stars 46 forks source link

Compiler is not thread-safe (re-entrant) #42

Closed dobesv closed 7 years ago

dobesv commented 7 years ago

Sometimes I get errors while compiling a template, but not always. I've also had cases where a template appeared to be corrupted.

Looking at the code I see that every Compiler instance shares an instance of CodeBuilder because the CodeBuilder is constructed as a class level field _builder instead of initializing in the constructor. CodeBuilder appears to use mutable fields in self while it compiles the code, so you cannot share an instance of CodeBuilder between instances of Compiler in parallel.

Traceback (most recent call last):
  File "/home/dobes/env/lib/python2.7/site-packages/pybars/_compiler.py", line 827, in compile
    container = self._generate_code(source)
  File "/home/dobes/env/lib/python2.7/site-packages/pybars/_compiler.py", line 801, in _generate_code
    output = self._compiler(tree).apply('compile')[0]
  File "/home/dobes/env/lib/python2.7/site-packages/pymeta/runtime.py", line 299, in apply
    val, err = self._apply(r, ruleName, args)
  File "/home/dobes/env/lib/python2.7/site-packages/pymeta/runtime.py", line 329, in _apply
    [rule(), self.input])
  File "/pymeta_generated_code/pymeta_grammar__Grammar.py", line 11, in rule_compile
    self.considerError(lastError)
  File "/home/dobes/env/lib/python2.7/site-packages/pymeta/runtime.py", line 396, in many
    v, _ = fn()
  File "/pymeta_generated_code/pymeta_grammar__Grammar.py", line 8, in _G_many_2
    _G_exactly_1, lastError = self.exactly('-')
  File "/home/dobes/env/lib/python2.7/site-packages/pymeta/runtime.py", line 329, in _apply
    [rule(), self.input])
  File "/pymeta_generated_code/pymeta_grammar__Grammar.py", line 59, in rule_rule
    return (_G_apply_1, self.currentError)
  File "/home/dobes/env/lib/python2.7/site-packages/pymeta/runtime.py", line 414, in _or
    ret, err = f()
  File "/pymeta_generated_code/pymeta_grammar__Grammar.py", line 48, in _G_or_5
    return (_G_apply_1, self.currentError)
  File "/home/dobes/env/lib/python2.7/site-packages/pymeta/runtime.py", line 329, in _apply
    [rule(), self.input])
  File "/pymeta_generated_code/pymeta_grammar__Grammar.py", line 107, in rule_block
    _locals['x'] = _G_apply_1
  File "<string>", line 1, in <module>
  File "/home/dobes/env/lib/python2.7/site-packages/pybars/_compiler.py", line 554, in add_block
    self._locals[name] = nested
TypeError: list indices must be integers, not str
AniX commented 7 years ago

@dobesv Have you tried to what happens if you initialize the CodeBuilder in the constructor of Compiler as object level instance?

I'm evaluating to switch from Mustache to Handlebars, and would need to replace pystache by a Python Handlebars implementation. And pybars3 looks good so far. To run it efficiently in Google App Engine, I would need it to be threadsafe though.

dobesv commented 7 years ago

I gave up on pybars3 and used a different template system instead. I haven't regretted it.

On Sat, Mar 18, 2017, 2:22 AM Anastasios Hatzis notifications@github.com wrote:

@dobesv https://github.com/dobesv Have you tried to what happens if you initialize the CodeBuilder in the constructor of Compiler as object level instance?

I'm evaluating to switch from Mustache to Handlebars, and would need to replace pystache by a Python Handlebars implementation. And pybars3 looks good so far. To run it efficiently in Google App Engine, I would need it to be threadsafe though.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/wbond/pybars3/issues/42#issuecomment-287528876, or mute the thread https://github.com/notifications/unsubscribe-auth/AAUAmTRDBg3CqybTOeMPGLoEPqDwCuSpks5rm6I_gaJpZM4LuAEW .

dobesv commented 7 years ago

There is no way to make it thread safe, you would just have to use a global lock when using pybars3.

On Sat, Mar 18, 2017, 9:09 AM Dobes Vandermeer dobesv@gmail.com wrote:

I gave up on pybars3 and used a different template system instead. I haven't regretted it.

On Sat, Mar 18, 2017, 2:22 AM Anastasios Hatzis notifications@github.com wrote:

@dobesv https://github.com/dobesv Have you tried to what happens if you initialize the CodeBuilder in the constructor of Compiler as object level instance?

I'm evaluating to switch from Mustache to Handlebars, and would need to replace pystache by a Python Handlebars implementation. And pybars3 looks good so far. To run it efficiently in Google App Engine, I would need it to be threadsafe though.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/wbond/pybars3/issues/42#issuecomment-287528876, or mute the thread https://github.com/notifications/unsubscribe-auth/AAUAmTRDBg3CqybTOeMPGLoEPqDwCuSpks5rm6I_gaJpZM4LuAEW .