Merge branch 'master' into release
This commit is contained in:
commit
e51b89df38
|
|
@ -16,8 +16,8 @@
|
|||
"@craco/craco": "^5.6.1",
|
||||
"@manaflair/redux-batch": "^1.0.0",
|
||||
"@optimizely/optimizely-sdk": "^4.0.0",
|
||||
"@sentry/react": "^5.22.3",
|
||||
"@sentry/tracing": "^5.22.3",
|
||||
"@sentry/react": "^5.24.2",
|
||||
"@sentry/tracing": "^5.24.2",
|
||||
"@sentry/webpack-plugin": "^1.12.1",
|
||||
"@types/chance": "^1.0.7",
|
||||
"@types/lodash": "^4.14.120",
|
||||
|
|
|
|||
|
|
@ -23,7 +23,12 @@ import {
|
|||
import { Icon } from "@blueprintjs/core";
|
||||
import moment from "moment";
|
||||
|
||||
const { algolia, appVersion, cloudHosting } = getAppsmithConfigs();
|
||||
const {
|
||||
algolia,
|
||||
appVersion,
|
||||
cloudHosting,
|
||||
intercomAppID,
|
||||
} = getAppsmithConfigs();
|
||||
const searchClient = algoliasearch(algolia.apiId, algolia.apiKey);
|
||||
|
||||
const OenLinkIcon = HelpIcons.OPEN_LINK;
|
||||
|
|
@ -108,6 +113,11 @@ const DefaultHelpMenuItem = (props: {
|
|||
id={props.item.id}
|
||||
onClick={() => {
|
||||
if (props.item.link) window.open(props.item.link, "_blank");
|
||||
if (props.item.id === "intercom-trigger") {
|
||||
if (cloudHosting && intercomAppID && window.Intercom) {
|
||||
window.Intercom("show");
|
||||
}
|
||||
}
|
||||
props.onSelect();
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ class HelpModal extends React.Component<Props> {
|
|||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
user_id: user?.username,
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
custom_launcher_selector: "#intercom-trigger",
|
||||
name: user?.name,
|
||||
email: user?.email,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import styled from "styled-components";
|
|||
import ExplorerSidebar from "pages/Editor/Explorer";
|
||||
import { PanelStack, Classes } from "@blueprintjs/core";
|
||||
import { Colors } from "constants/Colors";
|
||||
import * as Sentry from "@sentry/react";
|
||||
|
||||
const SidebarWrapper = styled.div`
|
||||
background-color: ${Colors.MINE_SHAFT};
|
||||
|
|
@ -32,4 +33,4 @@ export const Sidebar = memo(() => {
|
|||
|
||||
Sidebar.displayName = "Sidebar";
|
||||
|
||||
export default Sidebar;
|
||||
export default Sentry.withProfiler(Sidebar);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ import {
|
|||
getCurrentPageName,
|
||||
} from "selectors/editorSelectors";
|
||||
import ConfirmRunModal from "pages/Editor/ConfirmRunModal";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
} from "utils/PerformanceTracker";
|
||||
|
||||
const Section = styled.section`
|
||||
background: ${props => props.theme.colors.bodyBG};
|
||||
|
|
@ -108,11 +111,18 @@ class AppViewerPageContainer extends Component<AppViewerPageContainerProps> {
|
|||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: AppState) => ({
|
||||
isFetchingPage: getIsFetchingPage(state),
|
||||
widgets: getCanvasWidgetDsl(state),
|
||||
currentPageName: getCurrentPageName(state),
|
||||
});
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.GENERATE_VIEW_MODE_PROPS,
|
||||
);
|
||||
const props = {
|
||||
isFetchingPage: getIsFetchingPage(state),
|
||||
widgets: getCanvasWidgetDsl(state),
|
||||
currentPageName: getCurrentPageName(state),
|
||||
};
|
||||
PerformanceTracker.stopTracking();
|
||||
return props;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch: any) => ({
|
||||
fetchPage: (pageId: string, bustCache = false) =>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ import Spinner from "components/editorComponents/Spinner";
|
|||
import styled from "styled-components";
|
||||
import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper";
|
||||
import { changeApi } from "actions/apiPaneActions";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
} from "utils/PerformanceTracker";
|
||||
import * as Sentry from "@sentry/react";
|
||||
|
||||
const LoadingContainer = styled(CenteredWrapper)`
|
||||
height: 50%;
|
||||
|
|
@ -157,7 +161,6 @@ class ApiEditor extends React.Component<Props> {
|
|||
match={this.props.match}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
@ -214,7 +217,10 @@ const mapStateToProps = (state: AppState, props: any): ReduxStateProps => {
|
|||
const apiAction = getActionById(state, props);
|
||||
const apiName = getApiName(state, props.match.params.apiId);
|
||||
const { isDeleting, isRunning, isCreating } = state.ui.apiPane;
|
||||
return {
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.GENERATE_API_PROPS,
|
||||
);
|
||||
const apiEditorState = {
|
||||
actions: state.entities.actions,
|
||||
currentApplication: getCurrentApplication(state),
|
||||
currentPageName: getCurrentPageName(state),
|
||||
|
|
@ -229,6 +235,8 @@ const mapStateToProps = (state: AppState, props: any): ReduxStateProps => {
|
|||
isCreating,
|
||||
isEditorInitialized: getIsEditorInitialized(state),
|
||||
};
|
||||
PerformanceTracker.stopTracking();
|
||||
return apiEditorState;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch: any): ReduxActionProps => ({
|
||||
|
|
@ -240,4 +248,6 @@ const mapDispatchToProps = (dispatch: any): ReduxActionProps => ({
|
|||
changeAPIPage: (actionId: string) => dispatch(changeApi(actionId)),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ApiEditor);
|
||||
export default Sentry.withProfiler(
|
||||
connect(mapStateToProps, mapDispatchToProps)(ApiEditor),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import EntityProperty, { EntityPropertyProps } from "./EntityProperty";
|
||||
import { isFunction } from "lodash";
|
||||
import { entityDefinitions } from "utils/autocomplete/EntityDefinitions";
|
||||
|
|
@ -10,6 +10,10 @@ import {
|
|||
} from "entities/DataTree/dataTreeFactory";
|
||||
import { useSelector } from "react-redux";
|
||||
import { evaluateDataTreeWithoutFunctions } from "selectors/dataTreeSelectors";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
} from "utils/PerformanceTracker";
|
||||
import * as Sentry from "@sentry/react";
|
||||
|
||||
export const EntityProperties = (props: {
|
||||
entityType: ENTITY_TYPE;
|
||||
|
|
@ -18,6 +22,12 @@ export const EntityProperties = (props: {
|
|||
step: number;
|
||||
entity?: any;
|
||||
}) => {
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.ENTITY_EXPLORER_ENTITY,
|
||||
);
|
||||
useEffect(() => {
|
||||
PerformanceTracker.stopTracking();
|
||||
});
|
||||
let entity: any;
|
||||
const dataTree: DataTree = useSelector(evaluateDataTreeWithoutFunctions);
|
||||
if (props.isCurrentPage && dataTree[props.entityName]) {
|
||||
|
|
@ -27,7 +37,6 @@ export const EntityProperties = (props: {
|
|||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
let config: any;
|
||||
let entityProperties: Array<EntityPropertyProps> = [];
|
||||
switch (props.entityType) {
|
||||
|
|
@ -87,4 +96,4 @@ export const EntityProperties = (props: {
|
|||
);
|
||||
};
|
||||
|
||||
export default EntityProperties;
|
||||
export default Sentry.withProfiler(EntityProperties);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ import PropertyControl from "pages/Editor/PropertyPane/PropertyControl";
|
|||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
import * as log from "loglevel";
|
||||
import PaneWrapper from "pages/common/PaneWrapper";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
} from "utils/PerformanceTracker";
|
||||
|
||||
const PropertySectionLabel = styled.div`
|
||||
color: ${props => props.theme.colors.paneSectionLabel};
|
||||
|
|
@ -224,12 +227,17 @@ class PropertyPane extends Component<
|
|||
}
|
||||
|
||||
const mapStateToProps = (state: AppState): PropertyPaneProps => {
|
||||
return {
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.GENERATE_PROPERTY_PANE_PROPS,
|
||||
);
|
||||
const props = {
|
||||
propertySections: getPropertyConfig(state),
|
||||
widgetId: getCurrentWidgetId(state),
|
||||
widgetProperties: getWidgetPropsForPropertyPane(state),
|
||||
isVisible: getIsPropertyPaneVisible(state),
|
||||
};
|
||||
PerformanceTracker.stopTracking();
|
||||
return props;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch: any): PropertyPaneFunctions => {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ import { getCanvasClassName } from "utils/generators";
|
|||
import { flashElementById } from "utils/helpers";
|
||||
import { useParams } from "react-router";
|
||||
import { fetchPage } from "actions/pageActions";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
} from "utils/PerformanceTracker";
|
||||
|
||||
const EditorWrapper = styled.div`
|
||||
display: flex;
|
||||
|
|
@ -46,6 +49,9 @@ const CanvasContainer = styled.section`
|
|||
|
||||
/* eslint-disable react/display-name */
|
||||
const WidgetsEditor = () => {
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.GENERATE_WIDGET_EDITOR_PROPS,
|
||||
);
|
||||
const { focusWidget, selectWidget } = useWidgetSelection();
|
||||
const params = useParams<{ applicationId: string; pageId: string }>();
|
||||
const dispatch = useDispatch();
|
||||
|
|
@ -55,6 +61,10 @@ const WidgetsEditor = () => {
|
|||
const currentPageId = useSelector(getCurrentPageId);
|
||||
const currentPageName = useSelector(getCurrentPageName);
|
||||
|
||||
useEffect(() => {
|
||||
PerformanceTracker.stopTracking(PerformanceTransactionName.CLOSE_API);
|
||||
});
|
||||
|
||||
// Switch page
|
||||
useEffect(() => {
|
||||
if (currentPageId !== params.pageId && !!params.pageId) {
|
||||
|
|
@ -101,6 +111,7 @@ const WidgetsEditor = () => {
|
|||
node = <Canvas dsl={widgets} />;
|
||||
}
|
||||
log.debug("Canvas rendered");
|
||||
PerformanceTracker.stopTracking();
|
||||
return (
|
||||
<EditorContextProvider>
|
||||
<EditorWrapper onClick={handleWrapperClick}>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ import {
|
|||
} from "utils/hooks/dragResizeHooks";
|
||||
import { closeAllModals } from "actions/widgetActions";
|
||||
import { useDispatch } from "react-redux";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
} from "utils/PerformanceTracker";
|
||||
|
||||
const Wrapper = styled.div<{ isVisible: boolean }>`
|
||||
position: absolute;
|
||||
|
|
@ -78,6 +81,7 @@ class EditorsRouter extends React.Component<
|
|||
}
|
||||
|
||||
handleClose = (e: React.MouseEvent) => {
|
||||
PerformanceTracker.startTracking(PerformanceTransactionName.CLOSE_API);
|
||||
e.stopPropagation();
|
||||
const { applicationId, pageId } = this.props.match.params;
|
||||
this.setState({
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import React, { useEffect } from "react";
|
||||
import React from "react";
|
||||
import { Route } from "react-router-dom";
|
||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import { useSelector, connect } from "react-redux";
|
||||
import { connect } from "react-redux";
|
||||
import { getThemeDetails } from "selectors/themeSelectors";
|
||||
import { AppState } from "reducers";
|
||||
import { ThemeMode } from "reducers/uiReducers/themeReducer";
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ import { PLUGIN_PACKAGE_DBS } from "constants/QueryEditorConstants";
|
|||
import { RestAction } from "entities/Action";
|
||||
import { getCurrentOrgId } from "selectors/organizationSelectors";
|
||||
import log from "loglevel";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
} from "utils/PerformanceTracker";
|
||||
|
||||
function* syncApiParamsSaga(
|
||||
actionPayload: ReduxActionWithMeta<string, { field: string }>,
|
||||
|
|
@ -57,7 +60,7 @@ function* syncApiParamsSaga(
|
|||
const field = actionPayload.meta.field;
|
||||
const value = actionPayload.payload;
|
||||
const padQueryParams = { key: "", value: "" };
|
||||
|
||||
PerformanceTracker.startTracking(PerformanceTransactionName.SYNC_PARAMS_SAGA);
|
||||
if (field === "actionConfiguration.path") {
|
||||
if (value.indexOf("?") > -1) {
|
||||
const paramsString = value.substr(value.indexOf("?") + 1);
|
||||
|
|
@ -122,6 +125,7 @@ function* syncApiParamsSaga(
|
|||
),
|
||||
);
|
||||
}
|
||||
PerformanceTracker.stopTracking();
|
||||
}
|
||||
|
||||
function* initializeExtraFormDataSaga() {
|
||||
|
|
@ -162,6 +166,7 @@ function* changeApiSaga(actionPayload: ReduxAction<{ id: string }>) {
|
|||
// // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||
// // @ts-ignore
|
||||
// document.activeElement.blur();
|
||||
PerformanceTracker.startTracking(PerformanceTransactionName.CHANGE_API_SAGA);
|
||||
const { id } = actionPayload.payload;
|
||||
const action = yield select(getAction, id);
|
||||
if (!action) return;
|
||||
|
|
@ -187,6 +192,7 @@ function* changeApiSaga(actionPayload: ReduxAction<{ id: string }>) {
|
|||
id,
|
||||
);
|
||||
}
|
||||
PerformanceTracker.stopTracking();
|
||||
}
|
||||
|
||||
function* updateFormFields(
|
||||
|
|
|
|||
|
|
@ -7,39 +7,50 @@ import { getWidgets, getWidgetsMeta } from "sagas/selectors";
|
|||
import * as log from "loglevel";
|
||||
import "url-search-params-polyfill";
|
||||
import { getPageList } from "./appViewSelectors";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
} from "utils/PerformanceTracker";
|
||||
|
||||
export const getUnevaluatedDataTree = (withFunctions?: boolean) =>
|
||||
createSelector(
|
||||
getActionsForCurrentPage,
|
||||
getWidgets,
|
||||
getWidgetsMeta,
|
||||
getPageList,
|
||||
getAppData,
|
||||
(actions, widgets, widgetsMeta, pageListPayload, appData) => {
|
||||
const pageList = pageListPayload || [];
|
||||
return DataTreeFactory.create(
|
||||
{
|
||||
actions,
|
||||
widgets,
|
||||
widgetsMeta,
|
||||
pageList,
|
||||
appData,
|
||||
},
|
||||
withFunctions,
|
||||
);
|
||||
},
|
||||
);
|
||||
export const getUnevaluatedDataTree = createSelector(
|
||||
getActionsForCurrentPage,
|
||||
getWidgets,
|
||||
getWidgetsMeta,
|
||||
getPageList,
|
||||
getAppData,
|
||||
(actions, widgets, widgetsMeta, pageListPayload, appData) => {
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.CONSTRUCT_UNEVAL_TREE,
|
||||
);
|
||||
const pageList = pageListPayload || [];
|
||||
const unevalTree = DataTreeFactory.create(
|
||||
{
|
||||
actions,
|
||||
widgets,
|
||||
widgetsMeta,
|
||||
pageList,
|
||||
appData,
|
||||
},
|
||||
true,
|
||||
);
|
||||
PerformanceTracker.stopTracking();
|
||||
return unevalTree;
|
||||
},
|
||||
);
|
||||
|
||||
export const evaluateDataTree = (withFunctions?: boolean) =>
|
||||
createSelector(
|
||||
getUnevaluatedDataTree(withFunctions),
|
||||
(dataTree: DataTree): DataTree => {
|
||||
return getEvaluatedDataTree(dataTree);
|
||||
},
|
||||
);
|
||||
export const evaluateDataTree = createSelector(
|
||||
getUnevaluatedDataTree,
|
||||
(dataTree: DataTree): DataTree => {
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.DATA_TREE_EVALUATION,
|
||||
);
|
||||
const evalDataTree = getEvaluatedDataTree(dataTree);
|
||||
PerformanceTracker.stopTracking();
|
||||
return evalDataTree;
|
||||
},
|
||||
);
|
||||
|
||||
export const evaluateDataTreeWithFunctions = evaluateDataTree(true);
|
||||
export const evaluateDataTreeWithoutFunctions = evaluateDataTree(true);
|
||||
export const evaluateDataTreeWithFunctions = evaluateDataTree;
|
||||
export const evaluateDataTreeWithoutFunctions = evaluateDataTree;
|
||||
|
||||
// For autocomplete. Use actions cached responses if
|
||||
// there isn't a response already
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ import { DataTreeWidget } from "entities/DataTree/dataTreeFactory";
|
|||
import { getActions } from "sagas/selectors";
|
||||
|
||||
import * as log from "loglevel";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
} from "utils/PerformanceTracker";
|
||||
|
||||
const getWidgetConfigs = (state: AppState) => state.entities.widgetConfig;
|
||||
const getWidgetSideBar = (state: AppState) => state.ui.widgetSidebar;
|
||||
|
|
@ -107,6 +110,9 @@ export const getCanvasWidgetDsl = createSelector(
|
|||
entities: AppState["entities"],
|
||||
evaluatedDataTree,
|
||||
): ContainerWidgetProps<WidgetProps> => {
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.CONSTRUCT_CANVAS_DSL,
|
||||
);
|
||||
log.debug("Evaluating data tree to get canvas widgets");
|
||||
log.debug({ evaluatedDataTree });
|
||||
const widgets = { ...entities.canvasWidgets };
|
||||
|
|
@ -121,6 +127,7 @@ export const getCanvasWidgetDsl = createSelector(
|
|||
const denormalizedWidgets = CanvasWidgetsNormalizer.denormalize("0", {
|
||||
canvasWidgets: widgets,
|
||||
});
|
||||
PerformanceTracker.stopTracking();
|
||||
return denormalizedWidgets;
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,12 +15,14 @@ import {
|
|||
DataTreeWidget,
|
||||
ENTITY_TYPE,
|
||||
} from "entities/DataTree/dataTreeFactory";
|
||||
import * as log from "loglevel";
|
||||
import equal from "fast-deep-equal/es6";
|
||||
import WidgetFactory from "utils/WidgetFactory";
|
||||
import { AppToaster } from "components/editorComponents/ToastComponent";
|
||||
import { ToastType } from "react-toastify";
|
||||
import { Action } from "entities/Action";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
} from "utils/PerformanceTracker";
|
||||
|
||||
export const removeBindingsFromActionObject = (obj: Action) => {
|
||||
const string = JSON.stringify(obj);
|
||||
|
|
@ -261,52 +263,57 @@ let dependencyTreeCache: any = {};
|
|||
let cachedDataTreeString = "";
|
||||
|
||||
export function getEvaluatedDataTree(dataTree: DataTree): DataTree {
|
||||
const totalStart = performance.now();
|
||||
// Create Dependencies DAG
|
||||
const createDepsStart = performance.now();
|
||||
const dataTreeString = JSON.stringify(dataTree);
|
||||
// Stringify before doing a fast equals because the data tree has functions and fast equal will always treat those as changed values
|
||||
// Better solve will be to prune functions
|
||||
if (!equal(dataTreeString, cachedDataTreeString)) {
|
||||
const shouldCreateDependencyTree = !equal(
|
||||
dataTreeString,
|
||||
cachedDataTreeString,
|
||||
);
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.CREATE_DEPENDENCIES,
|
||||
{ isCacheMiss: shouldCreateDependencyTree },
|
||||
);
|
||||
if (shouldCreateDependencyTree) {
|
||||
cachedDataTreeString = dataTreeString;
|
||||
dependencyTreeCache = createDependencyTree(dataTree);
|
||||
}
|
||||
const createDepsEnd = performance.now();
|
||||
const {
|
||||
dependencyMap,
|
||||
sortedDependencies,
|
||||
dependencyTree,
|
||||
} = dependencyTreeCache;
|
||||
|
||||
PerformanceTracker.stopTracking();
|
||||
// Evaluate Tree
|
||||
const evaluatedTreeStart = performance.now();
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.SORTED_DEPENDENCY_EVALUATION,
|
||||
{
|
||||
dependencies: sortedDependencies,
|
||||
dependencyCount: sortedDependencies.length,
|
||||
dataTreeSize: cachedDataTreeString.length,
|
||||
},
|
||||
);
|
||||
const evaluatedTree = dependencySortedEvaluateDataTree(
|
||||
dataTree,
|
||||
dependencyMap,
|
||||
sortedDependencies,
|
||||
);
|
||||
const evaluatedTreeEnd = performance.now();
|
||||
PerformanceTracker.stopTracking();
|
||||
|
||||
// Set Loading Widgets
|
||||
const loadingTreeStart = performance.now();
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.SET_WIDGET_LOADING,
|
||||
);
|
||||
const treeWithLoading = setTreeLoading(evaluatedTree, dependencyTree);
|
||||
const loadingTreeEnd = performance.now();
|
||||
PerformanceTracker.stopTracking();
|
||||
|
||||
// Validate Widgets
|
||||
PerformanceTracker.startTracking(
|
||||
PerformanceTransactionName.VALIDATE_DATA_TREE,
|
||||
);
|
||||
const validated = getValidatedTree(treeWithLoading);
|
||||
|
||||
// End counting total time
|
||||
const endStart = performance.now();
|
||||
|
||||
// Log time taken and count
|
||||
const timeTaken = {
|
||||
total: (endStart - totalStart).toFixed(2),
|
||||
createDeps: (createDepsEnd - createDepsStart).toFixed(2),
|
||||
evaluate: (evaluatedTreeEnd - evaluatedTreeStart).toFixed(2),
|
||||
loading: (loadingTreeEnd - loadingTreeStart).toFixed(2),
|
||||
};
|
||||
log.debug("data tree evaluated");
|
||||
log.debug(timeTaken);
|
||||
PerformanceTracker.stopTracking();
|
||||
// dataTreeCache = validated;
|
||||
return validated;
|
||||
}
|
||||
|
|
@ -572,7 +579,6 @@ function evaluateDynamicProperty(
|
|||
if (isCacheHit && cacheObj) {
|
||||
return cacheObj.evaluated;
|
||||
} else {
|
||||
log.debug("eval " + propertyPath);
|
||||
const dynamicResult = getDynamicValue(unEvalPropertyValue, currentTree);
|
||||
dynamicPropValueCache.set(propertyPath, {
|
||||
evaluated: dynamicResult.result,
|
||||
|
|
|
|||
180
app/client/src/utils/PerformanceTracker.ts
Normal file
180
app/client/src/utils/PerformanceTracker.ts
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
import * as Sentry from "@sentry/react";
|
||||
import { Span, SpanStatus } from "@sentry/tracing";
|
||||
import _ from "lodash";
|
||||
import * as log from "loglevel";
|
||||
|
||||
export enum PerformanceTransactionName {
|
||||
DEPLOY_APPLICATION = "DEPLOY_APPLICATION",
|
||||
RUN_ACTION = "RUN_ACTION",
|
||||
PAGE_SWITCH_EDIT = "PAGE_SWITCH_EDIT",
|
||||
PAGE_SWITCH_VIEW = "PAGE_SWITCH_VIEW",
|
||||
CREATE_ACTION = "CREATE_ACTION",
|
||||
CURL_IMPORT = "CURL_IMPORT",
|
||||
EXECUTE_WIDGET_ACTION = "EXECUTE_WIDGET_ACTION",
|
||||
RUN_ACTION_WAIT_FOR_SAVE = "RUN_ACTION_WAIT_FOR_SAVE",
|
||||
DATA_TREE_EVALUATION = "DATA_TREE_EVALUATION",
|
||||
CONSTRUCT_UNEVAL_TREE = "CONSTRUCT_UNEVAL_TREE",
|
||||
CONSTRUCT_CANVAS_DSL = "CONSTRUCT_CANVAS_DSL",
|
||||
CREATE_DEPENDENCIES = "CREATE_DEPENDENCIES",
|
||||
SORTED_DEPENDENCY_EVALUATION = "SORTED_DEPENDENCY_EVALUATION",
|
||||
SET_WIDGET_LOADING = "SET_WIDGET_LOADING",
|
||||
VALIDATE_DATA_TREE = "VALIDATE_DATA_TREE",
|
||||
EXECUTE_PAGE_LOAD_ACTIONS = "EXECUTE_PAGE_LOAD_ACTIONS",
|
||||
SAVE_PAGE_LAYOUT = "SAVE_PAGE_LAYOUT",
|
||||
SAVE_ACTION = "SAVE_ACTION",
|
||||
EVALUATE_BINDING = "EVALUATE_BINDING",
|
||||
GENERATE_PROPERTY_PANE_PROPS = "GENERATE_PROPERTY_PANE_PROPS",
|
||||
GENERATE_VIEW_MODE_PROPS = "GENERATE_VIEW_MODE_PROPS",
|
||||
GENERATE_WIDGET_EDITOR_PROPS = "GENERATE_WIDGET_EDITOR_PROPS",
|
||||
ENTITY_EXPLORER_ENTITY = "ENTITY_EXPLORER_ENTITY",
|
||||
CLOSE_API = "CLOSE_API",
|
||||
OPEN_API = "OPEN_API",
|
||||
CANVAS_MOUNT = "CANVAS_MOUNT",
|
||||
GENERATE_API_PROPS = "GENERATE_API_PROPS",
|
||||
CHANGE_API_SAGA = "CHANGE_API_SAGA",
|
||||
SYNC_PARAMS_SAGA = "SYNC_PARAMS_SAGA",
|
||||
}
|
||||
|
||||
export enum PerformanceTagNames {
|
||||
PAGE_ID = "pageId",
|
||||
APP_ID = "appId",
|
||||
APP_MODE = "appMode",
|
||||
TRANSACTION_SUCCESS = "transaction.success",
|
||||
}
|
||||
|
||||
export interface PerfLog {
|
||||
sentrySpan: Span;
|
||||
skipLog?: boolean;
|
||||
eventName: string;
|
||||
}
|
||||
|
||||
class PerformanceTracker {
|
||||
private static perfLogQueue: PerfLog[] = [];
|
||||
|
||||
static startTracking = (
|
||||
eventName: PerformanceTransactionName,
|
||||
data?: any,
|
||||
skipLog = false,
|
||||
) => {
|
||||
const currentTransaction = Sentry.getCurrentHub()
|
||||
.getScope()
|
||||
?.getTransaction();
|
||||
if (
|
||||
PerformanceTracker.perfLogQueue.length === 0 &&
|
||||
currentTransaction !== undefined &&
|
||||
currentTransaction.status === SpanStatus.Ok
|
||||
) {
|
||||
PerformanceTracker.perfLogQueue.push({
|
||||
sentrySpan: currentTransaction,
|
||||
skipLog: skipLog,
|
||||
eventName: eventName,
|
||||
});
|
||||
}
|
||||
if (PerformanceTracker.perfLogQueue.length === 0) {
|
||||
if (!skipLog) {
|
||||
log.debug(
|
||||
PerformanceTracker.generateSpaces(
|
||||
PerformanceTracker.perfLogQueue.length + 1,
|
||||
) +
|
||||
eventName +
|
||||
" Track Transaction ",
|
||||
);
|
||||
}
|
||||
const newTransaction = Sentry.startTransaction({ name: eventName });
|
||||
Sentry.getCurrentHub().configureScope(scope =>
|
||||
scope.setSpan(newTransaction),
|
||||
);
|
||||
PerformanceTracker.perfLogQueue.push({
|
||||
sentrySpan: newTransaction,
|
||||
skipLog: skipLog,
|
||||
eventName: eventName,
|
||||
});
|
||||
} else {
|
||||
if (!skipLog) {
|
||||
log.debug(
|
||||
PerformanceTracker.generateSpaces(
|
||||
PerformanceTracker.perfLogQueue.length + 1,
|
||||
) +
|
||||
eventName +
|
||||
" Track Span ",
|
||||
);
|
||||
}
|
||||
const currentPerfLog =
|
||||
PerformanceTracker.perfLogQueue[
|
||||
PerformanceTracker.perfLogQueue.length - 1
|
||||
];
|
||||
const currentRunningSpan = currentPerfLog.sentrySpan;
|
||||
const span = currentRunningSpan.startChild({ op: eventName, data: data });
|
||||
PerformanceTracker.perfLogQueue.push({
|
||||
sentrySpan: span,
|
||||
skipLog: skipLog,
|
||||
eventName: eventName,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
static stopTracking = (
|
||||
data?: any,
|
||||
eventName?: PerformanceTransactionName,
|
||||
) => {
|
||||
if (eventName) {
|
||||
let index = -1;
|
||||
_.forEach(PerformanceTracker.perfLogQueue, (perfLog, i) => {
|
||||
if (perfLog.eventName === eventName) {
|
||||
index = i;
|
||||
}
|
||||
if (index !== -1 && i >= index) {
|
||||
const currentSpan = perfLog.sentrySpan;
|
||||
currentSpan.finish();
|
||||
if (!perfLog?.skipLog) {
|
||||
PerformanceTracker.printDuration(
|
||||
perfLog.eventName,
|
||||
PerformanceTracker.perfLogQueue.length + 1,
|
||||
currentSpan.startTimestamp,
|
||||
currentSpan.endTimestamp,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
PerformanceTracker.perfLogQueue = PerformanceTracker.perfLogQueue.splice(
|
||||
index,
|
||||
);
|
||||
} else {
|
||||
const perfLog = PerformanceTracker.perfLogQueue.pop();
|
||||
if (perfLog) {
|
||||
const currentRunningSpan = perfLog?.sentrySpan;
|
||||
currentRunningSpan.setData("endData", data);
|
||||
currentRunningSpan.finish();
|
||||
if (!perfLog?.skipLog) {
|
||||
PerformanceTracker.printDuration(
|
||||
perfLog.eventName,
|
||||
PerformanceTracker.perfLogQueue.length + 1,
|
||||
currentRunningSpan.startTimestamp,
|
||||
currentRunningSpan.endTimestamp,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static generateSpaces(num: number) {
|
||||
let str = "";
|
||||
for (let i = 0; i < num; i++) {
|
||||
str += "\t";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static printDuration(
|
||||
eventName: string,
|
||||
level: number,
|
||||
startTime: number,
|
||||
endTime?: number,
|
||||
) {
|
||||
const duration = ((endTime || 0) - startTime) * 1000;
|
||||
const spaces = PerformanceTracker.generateSpaces(level);
|
||||
log.debug(spaces + eventName + " Finish Tracking in " + duration + "ms");
|
||||
}
|
||||
}
|
||||
|
||||
export default PerformanceTracker;
|
||||
|
|
@ -2719,14 +2719,14 @@
|
|||
dependencies:
|
||||
any-observable "^0.3.0"
|
||||
|
||||
"@sentry/browser@5.22.3":
|
||||
version "5.22.3"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.22.3.tgz#7a64bd1cf01bf393741a3e4bf35f82aa927f5b4e"
|
||||
integrity sha512-2TzE/CoBa5ZkvxJizDdi1Iz1ldmXSJpFQ1mL07PIXBjCt0Wxf+WOuFSj5IP4L40XHfJE5gU8wEvSH0VDR8nXtA==
|
||||
"@sentry/browser@5.24.2":
|
||||
version "5.24.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.24.2.tgz#e2c2786dbf07699ee12f12babf0138d633abc494"
|
||||
integrity sha512-P/uZC/VrLRpU7MVEJnlZK5+AkEmuHu+mns5gC91Z4gjn7GamjR/CaXVedHGw/15ZrsQiAiwoWwuxpv4Ypd/+SA==
|
||||
dependencies:
|
||||
"@sentry/core" "5.22.3"
|
||||
"@sentry/types" "5.22.3"
|
||||
"@sentry/utils" "5.22.3"
|
||||
"@sentry/core" "5.24.2"
|
||||
"@sentry/types" "5.24.2"
|
||||
"@sentry/utils" "5.24.2"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/cli@^1.55.0":
|
||||
|
|
@ -2740,69 +2740,69 @@
|
|||
progress "^2.0.3"
|
||||
proxy-from-env "^1.1.0"
|
||||
|
||||
"@sentry/core@5.22.3":
|
||||
version "5.22.3"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.22.3.tgz#030f435f2b518f282ba8bd954dac90cd70888bd7"
|
||||
integrity sha512-eGL5uUarw3o4i9QUb9JoFHnhriPpWCaqeaIBB06HUpdcvhrjoowcKZj1+WPec5lFg5XusE35vez7z/FPzmJUDw==
|
||||
"@sentry/core@5.24.2":
|
||||
version "5.24.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.24.2.tgz#1724652855c0887a690c3fc6acd2519d4072b511"
|
||||
integrity sha512-nuAwCGU1l9hgMinl5P/8nIQGRXDP2FI9cJnq5h1qiP/XIOvJkJz2yzBR6nTyqr4vBth0tvxQJbIpDNGd7vHJLg==
|
||||
dependencies:
|
||||
"@sentry/hub" "5.22.3"
|
||||
"@sentry/minimal" "5.22.3"
|
||||
"@sentry/types" "5.22.3"
|
||||
"@sentry/utils" "5.22.3"
|
||||
"@sentry/hub" "5.24.2"
|
||||
"@sentry/minimal" "5.24.2"
|
||||
"@sentry/types" "5.24.2"
|
||||
"@sentry/utils" "5.24.2"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/hub@5.22.3":
|
||||
version "5.22.3"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.22.3.tgz#08309a70d2ea8d5e313d05840c1711f34f2fffe5"
|
||||
integrity sha512-INo47m6N5HFEs/7GMP9cqxOIt7rmRxdERunA3H2L37owjcr77MwHVeeJ9yawRS6FMtbWXplgWTyTIWIYOuqVbw==
|
||||
"@sentry/hub@5.24.2":
|
||||
version "5.24.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.24.2.tgz#64a02fd487599945e488ae23aba4ce4df44ee79e"
|
||||
integrity sha512-xmO1Ivvpb5Qr9WgekinuZZlpl9Iw7iPETUe84HQOhUrXf+2gKO+LaUYMMsYSVDwXQEmR6/tTMyOtS6iavldC6w==
|
||||
dependencies:
|
||||
"@sentry/types" "5.22.3"
|
||||
"@sentry/utils" "5.22.3"
|
||||
"@sentry/types" "5.24.2"
|
||||
"@sentry/utils" "5.24.2"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/minimal@5.22.3":
|
||||
version "5.22.3"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.22.3.tgz#706e4029ae5494123d3875c658ba8911aa5cc440"
|
||||
integrity sha512-HoINpYnVYCpNjn2XIPIlqH5o4BAITpTljXjtAftOx6Hzj+Opjg8tR8PWliyKDvkXPpc4kXK9D6TpEDw8MO0wZA==
|
||||
"@sentry/minimal@5.24.2":
|
||||
version "5.24.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.24.2.tgz#14e8b136842398a32987459f0574359b6dc57a1f"
|
||||
integrity sha512-biFpux5bI3R8xiD/Zzvrk1kRE6bqPtfWXmZYAHRtaUMCAibprTKSY9Ta8QYHynOAEoJ5Akedy6HUsEkK5DoZfA==
|
||||
dependencies:
|
||||
"@sentry/hub" "5.22.3"
|
||||
"@sentry/types" "5.22.3"
|
||||
"@sentry/hub" "5.24.2"
|
||||
"@sentry/types" "5.24.2"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/react@^5.22.3":
|
||||
version "5.22.3"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.22.3.tgz#ed692f9e2aff718da6cd15d2941ddda4f1d63385"
|
||||
integrity sha512-Or/tLayuxpOJhIWOXiDKdaJQZ981uRS9NT0QcPvU+Si1qTElSqtH1zB94GlwhgpglkbmLPiYq6VPrG2HOiZ79Q==
|
||||
"@sentry/react@^5.24.2":
|
||||
version "5.24.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.24.2.tgz#781ae4274ad5c3148b8f80b613c1b0a73f763e47"
|
||||
integrity sha512-iVti69qCMFztgP2E0LMx6V+3+ppKdylMJalWnwMt4LyL9idnnuiwFzMCA9g3QEvXRCTSuqEO39Dk4XYXyxi8pA==
|
||||
dependencies:
|
||||
"@sentry/browser" "5.22.3"
|
||||
"@sentry/minimal" "5.22.3"
|
||||
"@sentry/types" "5.22.3"
|
||||
"@sentry/utils" "5.22.3"
|
||||
"@sentry/browser" "5.24.2"
|
||||
"@sentry/minimal" "5.24.2"
|
||||
"@sentry/types" "5.24.2"
|
||||
"@sentry/utils" "5.24.2"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/tracing@^5.22.3":
|
||||
version "5.22.3"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.22.3.tgz#9b5a376e3164c007a22e8642ec094104468cac0c"
|
||||
integrity sha512-Zp59kMCk5v56ZAyErqjv/QvGOWOQ5fRltzeVQVp8unIDTk6gEFXfhwPsYHOokJe1mfkmrgPDV6xAkYgtL3KCDQ==
|
||||
"@sentry/tracing@^5.24.2":
|
||||
version "5.24.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.24.2.tgz#a36b4f9bf699c5e07e99a148360091c8e727c51f"
|
||||
integrity sha512-1uDgvGGVF8lb3hRXbhNnns+8DBUKjhRKOFR5Z3RExjrDFYTDbHmoNtV73Q12Ra+Iht9HTZnIBOqYD3oSZIbJ0w==
|
||||
dependencies:
|
||||
"@sentry/hub" "5.22.3"
|
||||
"@sentry/minimal" "5.22.3"
|
||||
"@sentry/types" "5.22.3"
|
||||
"@sentry/utils" "5.22.3"
|
||||
"@sentry/hub" "5.24.2"
|
||||
"@sentry/minimal" "5.24.2"
|
||||
"@sentry/types" "5.24.2"
|
||||
"@sentry/utils" "5.24.2"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/types@5.22.3":
|
||||
version "5.22.3"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.22.3.tgz#d1d547b30ee8bd7771fa893af74c4f3d71f0fd18"
|
||||
integrity sha512-cv+VWK0YFgCVDvD1/HrrBWOWYG3MLuCUJRBTkV/Opdy7nkdNjhCAJQrEyMM9zX0sac8FKWKOHT0sykNh8KgmYw==
|
||||
"@sentry/types@5.24.2":
|
||||
version "5.24.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.24.2.tgz#e2c25d1e75d8dbec5dbbd9a309a321425b61c2ca"
|
||||
integrity sha512-HcOK00R0tQG5vzrIrqQ0jC28+z76jWSgQCzXiessJ5SH/9uc6NzdO7sR7K8vqMP2+nweCHckFohC8G0T1DLzuQ==
|
||||
|
||||
"@sentry/utils@5.22.3":
|
||||
version "5.22.3"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.22.3.tgz#e3bda3e789239eb16d436f768daa12829f33d18f"
|
||||
integrity sha512-AHNryXMBvIkIE+GQxTlmhBXD0Ksh+5w1SwM5qi6AttH+1qjWLvV6WB4+4pvVvEoS8t5F+WaVUZPQLmCCWp6zKw==
|
||||
"@sentry/utils@5.24.2":
|
||||
version "5.24.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.24.2.tgz#90b7dff939bbbf4bb8edcac6aac2d04a0552af80"
|
||||
integrity sha512-oPGde4tNEDHKk0Cg9q2p0qX649jLDUOwzJXHKpd0X65w3A6eJByDevMr8CSzKV9sesjrUpxqAv6f9WWlz185tA==
|
||||
dependencies:
|
||||
"@sentry/types" "5.22.3"
|
||||
"@sentry/types" "5.24.2"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/webpack-plugin@^1.12.1":
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user