We noticed that occasionally a [:print] media style declaration would render incorrectly. After setting up a minimal-case project, we were unable to recreate the issue at all. It seems that the size of a project (the number of defstyleds) plays an important role in recreating the bug. The issue happens inconsistently (not the same elements) and occasionally (not every time), which smells like a race condition.
The consequence of the problem is this:
A [style block, generated class name] is occasionally the correct style block attached to a randomly incorrect class name. The incorrect class name will be any random class generated from another defstyled that does not have a gensym as part of the name (this was our first clue).
It looks like almost every place cls is used, it's passed in as a fn argument. In this particular builder there's a mix of using the provided cls and directly accessing the c/env*. The only thing I can imagine is that there's a race condition and/or a stale atom state causing a mismatch between the two values at the time of style generation.
We will start looking into a fix for this, but after a short glance it's not immediately clear the purpose of the c/env* atom, and why it's even needed? There's a reducer that modifies the atom's :id value https://github.com/roman01la/cljss/blob/master/src/cljss/collect.clj#L25 , but I don't understand why that couldn't be performed as a local var inside the fn instead of a global atom.
Any context you could provide would greatly help and ensure that we don't submit a PR that's completely bonkers.
This is a doozy.
We noticed that occasionally a
[:print]
media style declaration would render incorrectly. After setting up a minimal-case project, we were unable to recreate the issue at all. It seems that the size of a project (the number ofdefstyled
s) plays an important role in recreating the bug. The issue happens inconsistently (not the same elements) and occasionally (not every time), which smells like a race condition.The consequence of the problem is this: A [style block, generated class name] is occasionally the correct style block attached to a randomly incorrect class name. The incorrect class name will be any random class generated from another
defstyled
that does not have a gensym as part of the name (this was our first clue).This is what happens on the first compilation:
Notice that the
.guidebook_views_priority-actions__h2-s
is incorrect (it's not the expectedguidebook_views_stress-test-results__subtitle-s
).If we save that particular
guidebook.views.stress_test_results
file and look at the compiled output again:We get the correct class name under the
@media print
block.We dug through the code to what we believe is the source of the problem: https://github.com/roman01la/cljss/blob/master/src/cljss/builder.clj#L10-L43 .
It looks like almost every place
cls
is used, it's passed in as a fn argument. In this particular builder there's a mix of using the providedcls
and directly accessing thec/env*
. The only thing I can imagine is that there's a race condition and/or a stale atom state causing a mismatch between the two values at the time of style generation.We will start looking into a fix for this, but after a short glance it's not immediately clear the purpose of the
c/env*
atom, and why it's even needed? There's a reducer that modifies the atom's:id
value https://github.com/roman01la/cljss/blob/master/src/cljss/collect.clj#L25 , but I don't understand why that couldn't be performed as a local var inside the fn instead of a global atom.Any context you could provide would greatly help and ensure that we don't submit a PR that's completely bonkers.