Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d7288b8
chore: cache allKeys and dependencyMap computation on client
Aug 29, 2024
502aeaa
Add fn to check if the computation is cached
Aug 29, 2024
c2db605
Move exported types to a seperate file
Aug 29, 2024
795e3fc
Change evalTree to async fn
Aug 30, 2024
8c16bfb
Merge remote-tracking branch 'origin' into chore/cache-eval-computati…
Aug 30, 2024
0c89ada
Merge remote-tracking branch 'origin' into chore/cache-eval-computati…
Aug 30, 2024
e6fd4a2
Merge remote-tracking branch 'origin' into chore/cache-eval-computati…
Sep 9, 2024
0e9b52d
Change evalTree and setupFirstTree to async fns
Sep 9, 2024
d7ff9e3
Add caching for allkeys and dep map calculations
Sep 9, 2024
5a2244c
Revert allKeys caching
Sep 9, 2024
d4a61f9
chore: remove published page fetch in view mode and reuse the consoli…
Sep 10, 2024
dce5339
Add comments
Sep 10, 2024
9ff7947
Revert changes
Sep 10, 2024
a2710a0
Patch fix for double dispatch of FETCH_ALL_PAGE_ENTITY_COMPLETION
Sep 10, 2024
6e24abf
Check for undefined timestamp
Sep 10, 2024
2119599
type refactor
Sep 10, 2024
2a426f0
Merge remote-tracking branch 'origin' into chore/cache-eval-computati…
Sep 11, 2024
cc3e898
arguments refactor
Sep 11, 2024
853beb3
Add timestamp to cache key and delete invalid cache entries for old t…
Sep 11, 2024
51d54c2
Profile add nodes and addDependency methods in createDepMap fn
Sep 11, 2024
a9c693c
Add test cases
Sep 11, 2024
21327a0
Fix test cases for EvaluationSaga
Sep 11, 2024
11de620
Fix test cases
Sep 11, 2024
5c8803e
Merge remote-tracking branch 'origin' into chore/cache-eval-computati…
Sep 14, 2024
54bdb16
await setupFirstTree in beforeEach
Sep 14, 2024
c72291c
Add dynamic timestamp for setupFirstTree in DataTreeEvaluator test cases
Sep 14, 2024
85535c4
Update test cases
Sep 16, 2024
726c80e
fix: remove redundant eval trigger
Sep 19, 2024
0a18cfe
fix type in jest test
Sep 19, 2024
74b96f6
Add a comment and change the debounce timer to 5 seconds
Sep 20, 2024
002a021
Merge remote-tracking branch 'origin' into chore/cache-eval-computati…
Sep 20, 2024
59286e6
Merge remote-tracking branch 'origin' into chore/cache-eval-computati…
Sep 20, 2024
2df05ed
revert patch fix
Sep 20, 2024
24be553
Merge branch 'fix/redundant-eval-trigger-ce', remote-tracking branch …
Sep 20, 2024
d84db3f
Merge remote-tracking branch 'origin' into chore/cache-eval-computati…
Oct 14, 2024
744bff1
Fix lint issues
Oct 14, 2024
dfcadfe
Remove workspace id from cache props
Oct 15, 2024
a42791b
fix test cases after prev change
Oct 15, 2024
af545a2
fix test cases after prev change
Oct 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion app/client/src/UITelemetry/generateWebWorkerTraces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface WebworkerSpanData {
//to regular otlp telemetry data and subsequently exported to our telemetry collector
export const newWebWorkerSpanData = (
spanName: string,
attributes: SpanAttributes,
attributes: SpanAttributes = {},
): WebworkerSpanData => {
return {
attributes,
Expand All @@ -28,6 +28,21 @@ const addEndTimeForWebWorkerSpanData = (span: WebworkerSpanData) => {
span.endTime = Date.now();
};

export const profileAsyncFn = async <T>(
spanName: string,
fn: () => Promise<T>,
allSpans: Record<string, WebworkerSpanData | SpanAttributes>,
attributes: SpanAttributes = {},
) => {
const span = newWebWorkerSpanData(spanName, attributes);
const res: T = await fn();

addEndTimeForWebWorkerSpanData(span);
allSpans[spanName] = span;

return res;
};

export const profileFn = <T>(
spanName: string,
attributes: SpanAttributes = {},
Expand Down
2 changes: 1 addition & 1 deletion app/client/src/ce/workers/Evaluation/evalWorkerActions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export enum EVAL_WORKER_SYNC_ACTION {
SETUP = "SETUP",
EVAL_TREE = "EVAL_TREE",
EVAL_ACTION_BINDINGS = "EVAL_ACTION_BINDINGS",
CLEAR_CACHE = "CLEAR_CACHE",
VALIDATE_PROPERTY = "VALIDATE_PROPERTY",
Expand All @@ -16,6 +15,7 @@ export enum EVAL_WORKER_SYNC_ACTION {
}

export enum EVAL_WORKER_ASYNC_ACTION {
EVAL_TREE = "EVAL_TREE",
EVAL_TRIGGER = "EVAL_TRIGGER",
EVAL_EXPRESSION = "EVAL_EXPRESSION",
LOAD_LIBRARIES = "LOAD_LIBRARIES",
Expand Down
49 changes: 49 additions & 0 deletions app/client/src/sagas/EvaluationsSaga.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ import {
} from "ee/constants/ReduxActionConstants";
import { fetchPluginFormConfigsSuccess } from "actions/pluginActions";
import { createJSCollectionSuccess } from "actions/jsActionActions";
import { getInstanceId } from "ee/selectors/tenantSelectors";
import {
getApplicationLastDeployedAt,
getCurrentApplicationId,
getCurrentPageId,
} from "selectors/editorSelectors";

jest.mock("loglevel");

describe("evaluateTreeSaga", () => {
Expand All @@ -40,8 +47,22 @@ describe("evaluateTreeSaga", () => {
[select(getSelectedAppTheme), {}],
[select(getAppMode), false],
[select(getWidgetsMeta), {}],
[select(getInstanceId), "instanceId"],
[select(getCurrentApplicationId), "applicationId"],
[select(getCurrentPageId), "pageId"],
[
select(getApplicationLastDeployedAt),
new Date("11 September 2024").toISOString(),
],
])
.call(evalWorker.request, EVAL_WORKER_ACTIONS.EVAL_TREE, {
cacheProps: {
instanceId: "instanceId",
appId: "applicationId",
pageId: "pageId",
appMode: false,
timestamp: new Date("11 September 2024").toISOString(),
},
unevalTree: unEvalAndConfigTree,
widgetTypeConfigMap: undefined,
widgets: {},
Expand Down Expand Up @@ -71,8 +92,22 @@ describe("evaluateTreeSaga", () => {
[select(getSelectedAppTheme), {}],
[select(getAppMode), false],
[select(getWidgetsMeta), {}],
[select(getInstanceId), "instanceId"],
[select(getCurrentApplicationId), "applicationId"],
[select(getCurrentPageId), "pageId"],
[
select(getApplicationLastDeployedAt),
new Date("11 September 2024").toISOString(),
],
])
.call(evalWorker.request, EVAL_WORKER_ACTIONS.EVAL_TREE, {
cacheProps: {
instanceId: "instanceId",
appId: "applicationId",
pageId: "pageId",
appMode: false,
timestamp: new Date("11 September 2024").toISOString(),
},
unevalTree: unEvalAndConfigTree,
widgetTypeConfigMap: undefined,
widgets: {},
Expand Down Expand Up @@ -111,8 +146,22 @@ describe("evaluateTreeSaga", () => {
[select(getSelectedAppTheme), {}],
[select(getAppMode), false],
[select(getWidgetsMeta), {}],
[select(getInstanceId), "instanceId"],
[select(getCurrentApplicationId), "applicationId"],
[select(getCurrentPageId), "pageId"],
[
select(getApplicationLastDeployedAt),
new Date("11 September 2024").toISOString(),
],
])
.call(evalWorker.request, EVAL_WORKER_ACTIONS.EVAL_TREE, {
cacheProps: {
instanceId: "instanceId",
appId: "applicationId",
pageId: "pageId",
appMode: false,
timestamp: new Date("11 September 2024").toISOString(),
},
unevalTree: unEvalAndConfigTree,
widgetTypeConfigMap: undefined,
widgets: {},
Expand Down
18 changes: 17 additions & 1 deletion app/client/src/sagas/EvaluationsSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ import { evalErrorHandler } from "./EvalErrorHandler";
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import { endSpan, startRootSpan } from "UITelemetry/generateTraces";
import { transformTriggerEvalErrors } from "ee/sagas/helpers";
import {
getApplicationLastDeployedAt,
getCurrentApplicationId,
getCurrentPageId,
} from "selectors/editorSelectors";
import { getInstanceId } from "ee/selectors/tenantSelectors";

const APPSMITH_CONFIGS = getAppsmithConfigs();

Expand Down Expand Up @@ -261,14 +267,24 @@ export function* evaluateTreeSaga(
yield select(getSelectedAppTheme);

log.debug({ unevalTree, configTree: unEvalAndConfigTree.configTree });

const instanceId: string = yield select(getInstanceId);
const applicationId: string = yield select(getCurrentApplicationId);
const pageId: string = yield select(getCurrentPageId);
const lastDeployedAt: string = yield select(getApplicationLastDeployedAt);
const appMode: ReturnType<typeof getAppMode> = yield select(getAppMode);
const widgetsMeta: ReturnType<typeof getWidgetsMeta> =
yield select(getWidgetsMeta);

const shouldRespondWithLogs = log.getLevel() === log.levels.DEBUG;

const evalTreeRequestData: EvalTreeRequestData = {
cacheProps: {
appMode,
appId: applicationId,
pageId,
timestamp: lastDeployedAt,
instanceId,
},
unevalTree: unEvalAndConfigTree,
widgetTypeConfigMap,
widgets,
Expand Down
16 changes: 14 additions & 2 deletions app/client/src/workers/Evaluation/__tests__/evaluation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import WidgetFactory from "WidgetProvider/factory";
import { generateDataTreeWidget } from "entities/DataTree/dataTreeWidget";
import { sortObjectWithArray } from "../../../utils/treeUtils";
import klona from "klona";
import { APP_MODE } from "entities/App";

const klonaFullSpy = jest.fn();

Expand Down Expand Up @@ -565,8 +566,19 @@ describe("DataTreeEvaluator", () => {

const evaluator = new DataTreeEvaluator(WIDGET_CONFIG_MAP);

it("Checks the number of clone operations in first tree flow", () => {
evaluator.setupFirstTree(unEvalTree, configTree);
it("Checks the number of clone operations in first tree flow", async () => {
await evaluator.setupFirstTree(
unEvalTree,
configTree,
{},
{
appId: "appId",
pageId: "pageId",
timestamp: "timestamp",
appMode: APP_MODE.PUBLISHED,
instanceId: "instanceId",
},
);
evaluator.evalAndValidateFirstTree();
// Hard check to not regress on the number of clone operations. Try to improve this number.
expect(klonaFullSpy).toBeCalledTimes(41);
Expand Down
16 changes: 14 additions & 2 deletions app/client/src/workers/Evaluation/evalTreeWithChanges.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { WidgetEntity } from "plugins/Linting/lib/entity/WidgetEntity";
import type { UpdateDataTreeMessageData } from "sagas/EvalWorkerActionSagas";
import DataTreeEvaluator from "workers/common/DataTreeEvaluator";
import * as evalTreeWithChanges from "./evalTreeWithChanges";
import { APP_MODE } from "entities/App";
export const BASE_WIDGET = {
widgetId: "randomID",
widgetName: "randomWidgetName",
Expand Down Expand Up @@ -184,9 +185,20 @@ describe("evaluateAndGenerateResponse", () => {
return updates.filter((p: any) => !p.rhs.__evaluation__);
};

beforeEach(() => {
beforeEach(async () => {
evaluator = new DataTreeEvaluator(WIDGET_CONFIG_MAP);
evaluator.setupFirstTree(unEvalTree, configTree);
await evaluator.setupFirstTree(
unEvalTree,
configTree,
{},
{
appId: "appId",
pageId: "pageId",
timestamp: "timestamp",
appMode: APP_MODE.PUBLISHED,
instanceId: "instanceId",
},
);
evaluator.evalAndValidateFirstTree();
});

Expand Down
52 changes: 27 additions & 25 deletions app/client/src/workers/Evaluation/handlers/evalTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@ import {
CrashingError,
getSafeToRenderDataTree,
} from "ee/workers/Evaluation/evaluationUtils";
import type {
EvalTreeRequestData,
EvalTreeResponseData,
EvalWorkerSyncRequest,
} from "../types";
import type { EvalTreeRequestData, EvalWorkerASyncRequest } from "../types";
import { clearAllIntervals } from "../fns/overrides/interval";
import JSObjectCollection from "workers/Evaluation/JSObject/Collection";
import { getJSVariableCreatedEvents } from "../JSObject/JSVariableEvents";
Expand All @@ -33,6 +29,7 @@ import { MessageType, sendMessage } from "utils/MessageUtil";
import {
profileFn,
newWebWorkerSpanData,
profileAsyncFn,
} from "UITelemetry/generateWebWorkerTraces";
import type { SpanAttributes } from "UITelemetry/generateTraces";
import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
Expand All @@ -49,9 +46,9 @@ export let canvasWidgetsMeta: Record<string, any>;
export let metaWidgetsCache: MetaWidgetsReduxState;
export let canvasWidgets: CanvasWidgetsReduxState;

export function evalTree(
request: EvalWorkerSyncRequest<EvalTreeRequestData>,
): EvalTreeResponseData {
export async function evalTree(
request: EvalWorkerASyncRequest<EvalTreeRequestData>,
) {
const { data, webworkerTelemetry } = request;

webworkerTelemetry["transferDataToWorkerThread"].endTime = Date.now();
Expand All @@ -76,6 +73,7 @@ export function evalTree(
affectedJSObjects,
allActionValidationConfig,
appMode,
cacheProps,
forceEvaluation,
metaWidgets,
shouldReplay,
Expand Down Expand Up @@ -109,16 +107,17 @@ export function evalTree(
allActionValidationConfig,
);

const setupFirstTreeResponse = profileFn(
const setupFirstTreeResponse = await profileAsyncFn(
"setupFirstTree",
{ description: "during initialisation" },
(dataTreeEvaluator as DataTreeEvaluator).setupFirstTree.bind(
dataTreeEvaluator,
unevalTree,
configTree,
webworkerTelemetry,
cacheProps,
),
webworkerTelemetry,
() =>
(dataTreeEvaluator as DataTreeEvaluator).setupFirstTree(
unevalTree,
configTree,
webworkerTelemetry,
),
{ description: "during initialisation" },
);

evalOrder = setupFirstTreeResponse.evalOrder;
Expand All @@ -128,8 +127,9 @@ export function evalTree(
"evalAndValidateFirstTree",
{ description: "during initialisation" },
webworkerTelemetry,
() =>
(dataTreeEvaluator as DataTreeEvaluator).evalAndValidateFirstTree(),
(dataTreeEvaluator as DataTreeEvaluator).evalAndValidateFirstTree.bind(
dataTreeEvaluator,
),
);

dataTree = makeEntityConfigsAsObjProperties(dataTreeResponse.evalTree, {
Expand Down Expand Up @@ -160,15 +160,17 @@ export function evalTree(
);
}

const setupFirstTreeResponse = profileFn(
const setupFirstTreeResponse = await profileAsyncFn(
"setupFirstTree",
{ description: "non-initialisation" },
(dataTreeEvaluator as DataTreeEvaluator).setupFirstTree.bind(
dataTreeEvaluator,
unevalTree,
configTree,
webworkerTelemetry,
cacheProps,
),
webworkerTelemetry,
() =>
(dataTreeEvaluator as DataTreeEvaluator).setupFirstTree(
unevalTree,
configTree,
),
{ description: "non-initialisation" },
);

isCreateFirstTree = true;
Expand Down
2 changes: 1 addition & 1 deletion app/client/src/workers/Evaluation/handlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const syncHandlerMap: Record<
(req: EvalWorkerSyncRequest) => any
> = {
[EVAL_WORKER_ACTIONS.EVAL_ACTION_BINDINGS]: evalActionBindings,
[EVAL_WORKER_ACTIONS.EVAL_TREE]: evalTree,
[EVAL_WORKER_ACTIONS.EVAL_TREE_WITH_CHANGES]: evalTreeWithChanges,
[EVAL_WORKER_ACTIONS.UNDO]: undo,
[EVAL_WORKER_ACTIONS.REDO]: redo,
Expand All @@ -52,6 +51,7 @@ const asyncHandlerMap: Record<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(req: EvalWorkerASyncRequest) => any
> = {
[EVAL_WORKER_ACTIONS.EVAL_TREE]: evalTree,
[EVAL_WORKER_ACTIONS.EVAL_TRIGGER]: evalTrigger,
[EVAL_WORKER_ACTIONS.EVAL_EXPRESSION]: evalExpression,
[EVAL_WORKER_ACTIONS.LOAD_LIBRARIES]: loadLibraries,
Expand Down
2 changes: 2 additions & 0 deletions app/client/src/workers/Evaluation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { APP_MODE } from "entities/App";
import type { WebworkerSpanData } from "UITelemetry/generateWebWorkerTraces";
import type { SpanAttributes } from "UITelemetry/generateTraces";
import type { AffectedJSObjects } from "sagas/EvaluationsSagaUtils";
import type { ICacheProps } from "../common/AppComputationCache/types";

// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -34,6 +35,7 @@ export type EvalWorkerASyncRequest<T = any> = WorkerRequest<
export type EvalWorkerResponse = EvalTreeResponseData | boolean | unknown;

export interface EvalTreeRequestData {
cacheProps: ICacheProps;
unevalTree: unEvalAndConfigTree;
widgetTypeConfigMap: WidgetTypeConfigMap;
widgets: CanvasWidgetsReduxState;
Expand Down
Loading