Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eager Execution #532

Closed
32 tasks done
jasmith-hs opened this issue Nov 12, 2020 · 1 comment
Closed
32 tasks done

Eager Execution #532

jasmith-hs opened this issue Nov 12, 2020 · 1 comment

Comments

@jasmith-hs
Copy link
Contributor

jasmith-hs commented Nov 12, 2020

This issue is to serve as the status and main point of info for the Eager Execution project that I'm working on.
Check out #519 for the initial draft PR that I opened for this project. (This PR will stay a draft)

Purpose

To partially render as much of a Jinjava/HubL template as possible to allow for a lightweight Jinjava engine to be used from the cdn worker at serve-time to eliminate as much serve-time dependency on the cos-renderer.

When executing eagerly, if there exist any deferred values in the Jinjava code, then the template will need to be rendered a second time with the values not deferred. The second render should have the same output as if the template was only rendered once, normally, with all values resolved on the context. Only the tags and functions that directly depend on the deferred values will end up getting deferred, and they are marked this way with a new set of objects called the context’s eagerTokens.

Background

TagNodes will become Deferred nodes if the tag.interpretOutput() throws a DeferredValueException. The node, which includes its children, will get put into the context’s deferredNodes. ExpressionNodes will become Deferred nodes if the expression within the tag throws a DeferredValueException when interpreter.resolveELExpression() is called.

Since the node and its children get deferred, it is unknown what kind of operations are therefore deferred. Additionally, there may be logic that could have been executed but got deferred because the parent node was deferred. Without eager execution, it is a requirement that an initial pass that results in deferred nodes, when rendered for a second pass, must be rendered with an engine with the same context.

Eager execution is therefore beneficial for 2 main reasons: The final rendering pass will be faster as there will be less unevaluated tags, functions, filters, and expressions to evaluate. And second, it allows for the final pass to be done by a different jinjava interpreter. (Limited access to functions, filters, etc; limited access to context; sandbox/separation from other services)

PR Backlog

Open main PR's

Merged PR's

(Branch) Execution Mode config option
Chunk Resolver
Introduce Eager Tokens
Tests and EagerTagDecorator skeleton
Run prepareContext method
Use strategy pattern for ExpressionNode
Full EagerTagDecorator Functionality (minus macro functions)
Add eager macro function logic
Eager expression node strategy
Length limiter
EagerIfTag
EagerForTag
EagerSetTag
EagerPrintTag & EagerDoTag
EagerCycleTag
Tests for extends and include tags
EagerImportTag & EagerFromTag

Progress

At the moment, everything in the below list is working and implemented, but I have made a checklist as I plan to introduce all the features in several different PRs (because it's way too much code for a single PR). I will check them off after the functionality and tests are merged in and will try to link the PR next to each item or something similar.

@jasmith-hs
Copy link
Contributor Author

jasmith-hs commented Nov 19, 2020

cc @Joeoh @boulter @hs-lsong @mattcoley in case you're interested in this project

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant