Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions backend/visitran/events/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ def parse_and_fire_reports() -> None:
status=iterate_result.status,
)
)
if iterate_result.end_status == str(ExecStatus.Success):
if iterate_result.end_status == ExecStatus.OK.value:
pass_count += 1
if iterate_result.end_status == str(ExecStatus.Warn):
elif iterate_result.end_status == ExecStatus.Warn.value:
warn_count += 1
if iterate_result.end_status == str(ExecStatus.Error):
elif iterate_result.end_status == ExecStatus.Fail.value:
error_count += 1
if iterate_result.end_status == str(ExecStatus.Skipped):
elif iterate_result.end_status == ExecStatus.Skipped.value:
skip_count += 1

functions.fire_event(
Expand Down
2 changes: 1 addition & 1 deletion backend/visitran/events/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ def message(self) -> str:


@dataclass
class UsingCachedObject(InfoLevel, proto_type.UsingCachedObject):
class UsingCachedObject(DebugLevel, proto_type.UsingCachedObject):
def code(self) -> str:
return "Z009"

Expand Down
32 changes: 16 additions & 16 deletions backend/visitran/visitran.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ def execute_graph(self) -> None:
destination_table_obj=(
str(node.destination_table_obj) if hasattr(node, "destination_table_obj") else ""
),
materialization=str(node.materialization),
materialization=node.materialization.value if hasattr(node.materialization, "value") else str(node.materialization),
select_statement=(str(node.select_statement) if hasattr(node, "select_statement") else ""),
source_schema_name=node.source_schema_name,
source_table_name=node.source_table_name,
Expand All @@ -276,8 +276,8 @@ def execute_graph(self) -> None:
ending_time=datetime.datetime.now(),
failures=False,
info_message=f"Running {node_name}",
status=str(ExecStatus.Success),
end_status=str(ExecStatus.OK),
status=ExecStatus.Success.value,
end_status=ExecStatus.OK.value,
)
sequence_number += 1
BASE_RESULT.append(base_result)
Expand All @@ -291,8 +291,8 @@ def execute_graph(self) -> None:
node_name=str(node_name),
sequence_num=sequence_number,
ending_time=datetime.datetime.now(),
status=str(ExecStatus.Error),
end_status=str(ExecStatus.Fail),
status=ExecStatus.Error.value,
end_status=ExecStatus.Fail.value,
info_message=f"Error occurred while running {node_name}",
failures=True,
)
Expand Down Expand Up @@ -438,7 +438,7 @@ def search_n_run_models(self, model_name: str = None, model_names: list = None)
)

for cls in cls_set:
fire_event(ProcessingModel(cls=str(cls)))
fire_event(ProcessingModel(cls=getattr(cls, "__name__", "") or file_name))
# process each model only once
# they might be imported in several places!

Expand Down Expand Up @@ -550,9 +550,9 @@ def search_n_run_tests(self) -> None:
sequence_num=test_files.index(tf),
failures=True,
ending_time=datetime.datetime.now(),
status=str(ExecStatus.Error),
status=ExecStatus.Error.value,
info_message=f"Error occured in {tf} execution",
end_status=str(ExecStatus.Fail),
end_status=ExecStatus.Fail.value,
)
BASE_RESULT.append(base_result)
parse_and_fire_reports()
Expand Down Expand Up @@ -611,8 +611,8 @@ def _run_tests(self, tf: str, tst_cls: Any, tst_obj: Any, test_methods: list[str
info_message=f"Test assertion error: \
{repr(err)} in {test_func.__name__}",
ending_time=datetime.datetime.now(),
status=str(ExecStatus.Error),
end_status=str(ExecStatus.Fail),
status=ExecStatus.Error.value,
end_status=ExecStatus.Fail.value,
sequence_num=sequence_num,
)
BASE_RESULT.append(base_result)
Expand All @@ -624,8 +624,8 @@ def _run_tests(self, tf: str, tst_cls: Any, tst_obj: Any, test_methods: list[str
ending_time=datetime.datetime.now(),
failures=False,
info_message=f"Running {tf}",
status=str(ExecStatus.Success),
end_status=str(ExecStatus.OK),
status=ExecStatus.Success.value,
end_status=ExecStatus.OK.value,
sequence_num=sequence_num,
)
BASE_RESULT.append(base_result)
Expand Down Expand Up @@ -727,14 +727,14 @@ def validate_and_run_seed(self, seed_file, session_id: str) -> dict[str, str]:
seed_result = SeedResult(
schema_name=schema,
seed_path=file_name,
status=str(ExecStatus.START),
status=ExecStatus.START.value,
)
SEED_RESULT.append(seed_result)
seed_obj: BaseSeed = self.db_adapter.run_seeds(schema=schema, abs_path=file_path)
seed_result = SeedResult(
schema_name=schema,
seed_path=file_name,
status=str(ExecStatus.COMPLETED),
status=ExecStatus.COMPLETED.value,
)
SEED_RESULT.append(seed_result)
parse_and_fire_seed_report()
Expand Down Expand Up @@ -789,14 +789,14 @@ def run_snapshot(self) -> None:
snapshot_result = SnapshotResult(
source_table=obj.source_table_name,
unique_key=obj.unique_key,
status=str(ExecStatus.START),
status=ExecStatus.START.value,
)
SNAPSHOT_RESULT.append(snapshot_result)
self.db_adapter.run_scd(visitran_snapshot=obj)
snapshot_result = SnapshotResult(
source_table=obj.source_table_name,
unique_key=obj.unique_key,
status=str(ExecStatus.COMPLETED),
status=ExecStatus.COMPLETED.value,
)
SNAPSHOT_RESULT.append(snapshot_result)
parse_and_fire_snapshot_report()
Expand Down
78 changes: 60 additions & 18 deletions frontend/src/ide/editor/no-code-model/no-code-model.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Input,
Modal,
Pagination,
Select,
Space,
Table,
Tabs,
Expand Down Expand Up @@ -206,7 +207,9 @@ function NoCodeModel({ nodeData }) {
const [seqEdges, setSeqEdges, onSeqEdgesChange] = useEdgesState();
const [reactFlowInstance, setReactFlowInstance] = useState(null);
const [logsInfo, setLogsInfo] = useState([]);
// const logsInfo = [];
const [logsLevel, setLogsLevel] = useState(
() => localStorage.getItem("visitran.logsLevel") || "info"
);
const [reveal, setReveal] = useState(false);
const [seqOrder, setSeqOrder] = useState({});
const [specRevert, setSpecRevert] = useState(false);
Expand Down Expand Up @@ -366,6 +369,23 @@ function NoCodeModel({ nodeData }) {
ALLOWED_ATTR: ["style"],
});

const LOG_LEVEL_RANK = { debug: 0, info: 1, warn: 2, warning: 2, error: 3 };
const LOG_LEVEL_COLOR = {
debug: "#8c8c8c",
info: undefined,
warn: "#d48806",
warning: "#d48806",
error: "#cf1322",
};
const filteredLogs = logsInfo.filter(
(entry) =>
(LOG_LEVEL_RANK[entry.level] ?? 1) >= (LOG_LEVEL_RANK[logsLevel] ?? 1)
);
Comment on lines +372 to +383
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Constants and derived state recreated on every render

LOG_LEVEL_RANK, LOG_LEVEL_COLOR, and filteredLogs are all recreated on every render. As logsInfo grows (common in long runs), the filter pass over the full array on every unrelated state change will become noticeable. Move the two lookup objects outside the component and wrap filteredLogs in useMemo:

// outside the component
const LOG_LEVEL_RANK = { debug: 0, info: 1, warn: 2, warning: 2, error: 3 };
const LOG_LEVEL_COLOR = { debug: "#8c8c8c", info: undefined, warn: "#d48806", warning: "#d48806", error: "#cf1322" };

// inside the component
const filteredLogs = useMemo(
  () => logsInfo.filter(
    (entry) => (LOG_LEVEL_RANK[entry.level] ?? 1) >= (LOG_LEVEL_RANK[logsLevel] ?? 1)
  ),
  [logsInfo, logsLevel]
);
Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/ide/editor/no-code-model/no-code-model.jsx
Line: 372-383

Comment:
**Constants and derived state recreated on every render**

`LOG_LEVEL_RANK`, `LOG_LEVEL_COLOR`, and `filteredLogs` are all recreated on every render. As `logsInfo` grows (common in long runs), the filter pass over the full array on every unrelated state change will become noticeable. Move the two lookup objects outside the component and wrap `filteredLogs` in `useMemo`:

```js
// outside the component
const LOG_LEVEL_RANK = { debug: 0, info: 1, warn: 2, warning: 2, error: 3 };
const LOG_LEVEL_COLOR = { debug: "#8c8c8c", info: undefined, warn: "#d48806", warning: "#d48806", error: "#cf1322" };

// inside the component
const filteredLogs = useMemo(
  () => logsInfo.filter(
    (entry) => (LOG_LEVEL_RANK[entry.level] ?? 1) >= (LOG_LEVEL_RANK[logsLevel] ?? 1)
  ),
  [logsInfo, logsLevel]
);
```

How can I resolve this? If you propose a fix, please make it concise.

const handleLogsLevelChange = (value) => {
setLogsLevel(value);
localStorage.setItem("visitran.logsLevel", value);
};

const hideGenAIAndTimeTravelTabs = true;
const BOTTOM_TABS = [
{
Expand Down Expand Up @@ -643,21 +663,43 @@ function NoCodeModel({ nodeData }) {
),
key: "logs",
children: (
<div
className="logsSection"
style={{
height: `calc(${bottomSectionRef.current.height} - 70px)`,
}}
>
{logsInfo?.map((el, index) => {
return (
<>
<div
style={{
display: "flex",
justifyContent: "flex-end",
padding: "4px 8px",
borderBottom: "1px solid #f0f0f0",
}}
>
<Select
size="small"
value={logsLevel}
onChange={handleLogsLevelChange}
style={{ width: 140 }}
options={[
{ value: "debug", label: "All logs" },
{ value: "info", label: "Info & above" },
{ value: "warn", label: "Warnings & errors" },
{ value: "error", label: "Errors only" },
]}
/>
</div>
<div
className="logsSection"
style={{
height: `calc(${bottomSectionRef.current.height} - 100px)`,
}}
>
{filteredLogs.map((el, index) => (
<div
key={index}
dangerouslySetInnerHTML={{ __html: parseLog(el) }}
></div>
);
})}
</div>
style={{ color: LOG_LEVEL_COLOR[el.level] }}
dangerouslySetInnerHTML={{ __html: parseLog(el.message) }}
/>
))}
</div>
</>
),
},
].filter((tab) => {
Expand Down Expand Up @@ -1768,16 +1810,16 @@ function NoCodeModel({ nodeData }) {
const sessionId = data.session_id;
// Listen for messages in the specific room (session ID)
newSocket.on(`logs:${sessionId}`, (data) => {
const temp = data?.data?.message;
const message = data?.data?.message;
const level = (data?.data?.level || "info").toLowerCase();
if (!message) return;
const doc = document.getElementsByClassName("logsSection");
if (doc[0]) {
setTimeout(() => {
doc[0].scrollTop = doc[0].scrollHeight;
}, 800);
}
setLogsInfo((old) => {
return [...old, temp];
});
setLogsInfo((old) => [...old, { level, message }]);
});
});
});
Expand Down
Loading