Cache EnvVars in ThreadLocal during sandboxed script/template execution#1568
Cache EnvVars in ThreadLocal during sandboxed script/template execution#1568Vinamra-tech wants to merge 2 commits intojenkinsci:mainfrom
Conversation
|
I really like this optimization. The way you use ThreadLocal caching is really clean. The try finally guarantee in ScriptContent is great because it makes sure there is no cross execution leakage. I have a thoughts on this
Overall I think the main idea of this optimization is really good and the performance numbers are very impressive. |
Hey @ArpanC6, thanks for the review! Addressing each point: 1. ENV_CACHE visibility — Valid, fixed. 2. Threshold assertion in testProfilingGain — Respectfully disagree. 3. Exception path coverage — Valid, fixed. 4. @DisplayName — Can't find precedent in the codebase. |
Thanks for addressing all the points and for the detailed explanation |
Caches
EnvVarsin aThreadLocalfor the duration of a single sandboxedscript/template execution to avoid redundant
build.getEnvironment(listener)calls on every variable lookup.
Previously,
getEnvironment()was called on every variable reference withina sandboxed Groovy email template — once in
permitsMethod()and again inmethodMissing(). This is an expensive I/O and CPU operation (merging nodevars, job properties, parameters, etc.). In large templates with many
variables, this results in significant redundant processing.
Changes:
EmailExtScriptTokenMacroWhitelist— addedstatic final ThreadLocal<EnvVars>,beginExecution(),endExecution(), and cache-first lookup inpermitsMethod()EmailExtScript— cache-first lookup inmethodMissing()with fallbackScriptContent—beginExecution/endExecutionwrapped intry-finallyaround both sandbox execution points (
renderTemplateandexecuteScript)EmailExtScriptTokenMacroWhiteListTest— new test class (JUnit 5)The cache lives purely in Java (not in the Groovy
Binding), so scriptscannot touch or mutate it. Cleanup is guaranteed via
finally, preventingany cross-execution leakage or memory retention.
Closes #1548
Follows up on #1542 (closed)
Testing done
Added
EmailExtScriptTokenMacroWhiteListTestcovering:testGetEnvironmentCalledOnlyOnce— verifies thatgetEnvironment()is called exactly once across multiple cache lookupstestCacheIsClearedAfterEndExecution— verifiesENV_CACHE.get()returns
nullafterendExecution()is calledtestFallbackWhenCacheNotInitialized— verifies graceful behaviorwhen
beginExecution()was never calledtestProfilingGain(@Tag("performance")) — benchmarks baseline vscached execution over 100 macro evaluations with 5 JVM warm-up runs
Profiling results (100 macro evaluations, 5ms simulated I/O per
getEnvironment()call, 5 JVM warm-up runs discarded):All 4 tests pass (
BUILD SUCCESS).Submitter checklist