app.engine.dsl_execution_context module¶
ExecutionContext: precomputes everything a strategy AST will need so the interpreter walk is pure CPU and never makes a database call.
The precompute strategy is deliberately lazy at the AST level: we walk
the tree once, collect the set of field paths it actually reads, and
only fetch (or mock) those. A strategy that ignores user.avg_time
pays no cost for it. A malicious AST that tries to reference an unknown
path is rejected by the validator long before we get here.
mock_state is the back door used by the /simulate endpoint: keys
are dotted-path strings matching FIELD_RESOLVERS entries (or data.*
prefixes). When present, the precompute uses the mock value verbatim and
never calls the analytics service. This is what lets a designer iterate
on logic against synthetic inputs while still hitting real production
analytics methods when mock_state is left unset.
- class app.engine.dsl_execution_context.ExecutionContext(externalGameId: 'str', externalTaskId: 'str', externalUserId: 'str', data: 'Mapping[str, Any]', resolved_fields: 'Mapping[str, Any]' = <factory>)[source]¶
Bases:
object- Parameters:
externalGameId (str)
externalTaskId (str)
externalUserId (str)
data (Mapping[str, Any])
resolved_fields (Mapping[str, Any])
- async classmethod build_for_ast(ast, *, externalGameId, externalTaskId, externalUserId, data, analytics_service, mock_state=None, parent_result=None, analytics_cache=None)[source]¶
Precompute every field referenced by
astand return a frozen context the interpreter can walk synchronously.The static paths are computed without any I/O. Analytics paths each trigger at most one awaited call to the analytics service, and only when the AST actually references them.
mock_stateshort-circuits both, useful for the simulate endpoint and for tests that don’t want a real DB.analytics_cacheis an optional caller-owned dict memoising analytics-field values within a single scoring call. DSL_EXTEND builds two contexts (pre + post) for the same user and request window; passing the same dict to both means each analytics method (a DB round-trip) runs once instead of twice. Onlyanalytics-kind fields are cached: static fields are pure CPU, anddata.*fields legitimately differ between phases because pre-rules may mutatedata. PassNone(the default) to opt out - DSL_FULL builds a single context and gains nothing.- Parameters:
ast (Dict[str, Any])
externalGameId (str)
externalTaskId (str)
externalUserId (str)
data (Dict[str, Any] | None)
analytics_service (Any)
mock_state (Dict[str, Any] | None)
parent_result (Dict[str, Any] | None)
analytics_cache (Dict[str, Any] | None)
- Return type: