diff --git a/src/brad/front_end/front_end.py b/src/brad/front_end/front_end.py index 001f5371..d00b47e0 100644 --- a/src/brad/front_end/front_end.py +++ b/src/brad/front_end/front_end.py @@ -194,7 +194,8 @@ async def serve_forever(self): await self._run_setup() # Start FlightSQL server - self._flight_sql_server.start() + if self._flight_sql_server is not None: + self._flight_sql_server.start() try: grpc_server = grpc.aio.server() @@ -288,7 +289,7 @@ async def _run_teardown(self): logger.debug("Starting BRAD front end _run_teardown()") # Shutdown FlightSQL server - if self._flight_sql_server: + if self._flight_sql_server is not None: self._flight_sql_server.stop() await self._sessions.end_all_sessions() diff --git a/src/brad/ui/manager_impl.py b/src/brad/ui/manager_impl.py index 99a31bd6..59a95fb7 100644 --- a/src/brad/ui/manager_impl.py +++ b/src/brad/ui/manager_impl.py @@ -2,12 +2,14 @@ import uvicorn import logging import importlib.resources as pkg_resources +import numpy as np from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from typing import Optional, List import brad.ui.static as brad_app from brad.blueprint import Blueprint +from brad.blueprint.table import Table from brad.blueprint.manager import BlueprintManager from brad.config.engine import Engine from brad.config.file import ConfigFile @@ -72,13 +74,20 @@ async def serve_forever(self) -> None: @app.get("/api/1/metrics") -def get_metrics(num_values: int = 3) -> MetricsData: +def get_metrics(num_values: int = 3, use_generated: bool = False) -> MetricsData: assert manager is not None metrics = manager.monitor.front_end_metrics().read_k_most_recent(k=num_values) qlat = metrics[FrontEndMetric.QueryLatencySecondP90.value] qlat_tm = TimestampedMetrics(timestamps=list(qlat.index), values=list(qlat)) tlat = metrics[FrontEndMetric.TxnLatencySecondP90.value] tlat_tm = TimestampedMetrics(timestamps=list(tlat.index), values=list(tlat)) + + if use_generated: + qlat_gen = np.random.normal(loc=15.0, scale=5.0, size=len(qlat)) + tlat_gen = np.random.normal(loc=0.015, scale=0.005, size=len(tlat)) + qlat_tm.values = list(qlat_gen) + tlat_tm.values = list(tlat_gen) + return MetricsData( named_metrics={ FrontEndMetric.QueryLatencySecondP90.value: qlat_tm, @@ -88,17 +97,40 @@ def get_metrics(num_values: int = 3) -> MetricsData: @app.get("/api/1/system_state") -def get_system_state() -> SystemState: +def get_system_state(filter_tables_for_demo: bool = False) -> SystemState: assert manager is not None blueprint = manager.blueprint_mgr.get_blueprint() - dbp = DisplayableBlueprint.from_blueprint(blueprint) # TODO: Hardcoded virtualized infrasturcture and writers. txn_tables = ["theatres", "showings", "ticket_orders", "movie_info", "aka_title"] txn_only = ["theatres", "showings", "ticket_orders"] + + if filter_tables_for_demo: + # To improve how the UI looks in a screenshot, we filter out some tables + # to reduce the amount of information shown. We keep up to 5 + + # len(txn_tables) around (upper bound). + relevant_tables: List[Table] = [] + max_tables = min(5, len(blueprint.tables())) + for table in blueprint.tables(): + if table.name in txn_tables or len(relevant_tables) < max_tables: + relevant_tables.append(table) + + new_locations = {} + for table in relevant_tables: + new_locations[table.name] = blueprint.get_table_locations(table.name) + blueprint = Blueprint( + schema_name=blueprint.schema_name(), + table_schemas=relevant_tables, + table_locations=new_locations, + aurora_provisioning=blueprint.aurora_provisioning(), + redshift_provisioning=blueprint.redshift_provisioning(), + full_routing_policy=blueprint.get_routing_policy(), + ) + + dbp = DisplayableBlueprint.from_blueprint(blueprint) vdbe1 = DisplayableVirtualEngine( name="VDBE 1", - freshness="Serializable", + freshness="No staleness (SI)", dialect="PostgreSQL SQL", peak_latency_s=0.030, tables=[ @@ -115,7 +147,7 @@ def get_system_state() -> SystemState: vdbe1.tables.sort(key=lambda t: t.name) vdbe2 = DisplayableVirtualEngine( name="VDBE 2", - freshness="≤ 10 minutes stale", + freshness="≤ 10 minutes stale (SI)", dialect="PostgreSQL SQL", peak_latency_s=30.0, tables=[ diff --git a/ui/index.html b/ui/index.html index 809d2a6c..8d14b226 100644 --- a/ui/index.html +++ b/ui/index.html @@ -9,7 +9,7 @@ href="https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap" rel="stylesheet" /> - BRAD + BRAD Dashboard
diff --git a/ui/src/App.jsx b/ui/src/App.jsx index 59315c0f..8e2d66db 100644 --- a/ui/src/App.jsx +++ b/ui/src/App.jsx @@ -53,7 +53,9 @@ function App() { useEffect(() => { let timeoutId = null; const refreshData = async () => { - const newSystemState = await fetchSystemState(); + const newSystemState = await fetchSystemState( + /*filterTablesForDemo=*/ true, + ); // TODO: Not the best way to check for equality. if (JSON.stringify(systemState) !== JSON.stringify(newSystemState)) { setSystemState(newSystemState); diff --git a/ui/src/api.js b/ui/src/api.js index 0e3eec79..7c03ac4f 100644 --- a/ui/src/api.js +++ b/ui/src/api.js @@ -2,15 +2,21 @@ import axios from "axios"; const API_PREFIX = "/api/1"; -async function fetchMetrics(numHistoricalValues) { +function flagToString(name, value) { + return `${name}=${value ? "true" : "false"}`; +} + +async function fetchMetrics(numHistoricalValues, useGenerated) { const result = await axios.get( - `${API_PREFIX}/metrics?num_values=${numHistoricalValues}`, + `${API_PREFIX}/metrics?num_values=${numHistoricalValues}&${flagToString("use_generated", useGenerated)}`, ); return result.data; } -async function fetchSystemState() { - const result = await axios.get(`${API_PREFIX}/system_state`); +async function fetchSystemState(filterTablesForDemo) { + const result = await axios.get( + `${API_PREFIX}/system_state?${flagToString("filter_tables_for_demo", filterTablesForDemo)}`, + ); return result.data; } diff --git a/ui/src/assets/brad_logo.png b/ui/src/assets/brad_logo.png new file mode 100644 index 00000000..c7a419a4 Binary files /dev/null and b/ui/src/assets/brad_logo.png differ diff --git a/ui/src/components/BlueprintView.jsx b/ui/src/components/BlueprintView.jsx index cf276d15..4d0d3682 100644 --- a/ui/src/components/BlueprintView.jsx +++ b/ui/src/components/BlueprintView.jsx @@ -9,10 +9,7 @@ function BlueprintView({ onTableHoverExit, }) { return ( - +
{blueprint && blueprint.engines && diff --git a/ui/src/components/Header.jsx b/ui/src/components/Header.jsx index 28f61f28..ec7be3a1 100644 --- a/ui/src/components/Header.jsx +++ b/ui/src/components/Header.jsx @@ -1,5 +1,5 @@ import "./styles/Header.css"; -import dbLogo from "../assets/db.svg"; +import bradLogo from "../assets/brad_logo.png"; function StatusText({ status, schema }) { if (!!schema) { @@ -28,7 +28,7 @@ function Header() {