From 89c11527b15bb785bbe38f8f6f80bb995d5c957e Mon Sep 17 00:00:00 2001 From: Bugen Zhao Date: Thu, 14 Mar 2024 16:58:41 +0800 Subject: [PATCH] feat(dashboard): embedded assets into binary for release builds (#15656) Signed-off-by: Bugen Zhao --- .github/workflows/dashboard_main.yml | 1 - .github/workflows/dashboard_pr.yml | 1 - Cargo.lock | 70 ++++++++++++++++- Cargo.toml | 2 + dashboard/next.config.js | 5 ++ dashboard/package-lock.json | 14 ++-- dashboard/package.json | 5 +- dashboard/pages/fragment_graph.tsx | 2 +- docker/Dockerfile | 2 +- docker/Dockerfile.hdfs | 2 +- src/meta/Cargo.toml | 1 + src/meta/dashboard/Cargo.toml | 34 ++++++++ src/meta/dashboard/build.rs | 77 +++++++++++++++++++ src/meta/dashboard/examples/serve.rs | 25 ++++++ src/meta/dashboard/src/embed.rs | 53 +++++++++++++ src/meta/dashboard/src/lib.rs | 50 ++++++++++++ .../{src/dashboard => dashboard/src}/proxy.rs | 30 ++++++-- src/meta/src/dashboard/mod.rs | 24 +----- src/workspace-hack/Cargo.toml | 4 + 19 files changed, 360 insertions(+), 42 deletions(-) create mode 100644 src/meta/dashboard/Cargo.toml create mode 100644 src/meta/dashboard/build.rs create mode 100644 src/meta/dashboard/examples/serve.rs create mode 100644 src/meta/dashboard/src/embed.rs create mode 100644 src/meta/dashboard/src/lib.rs rename src/meta/{src/dashboard => dashboard/src}/proxy.rs (77%) diff --git a/.github/workflows/dashboard_main.yml b/.github/workflows/dashboard_main.yml index cba5161310a37..0b9571b35154d 100644 --- a/.github/workflows/dashboard_main.yml +++ b/.github/workflows/dashboard_main.yml @@ -22,7 +22,6 @@ jobs: npm install npm run lint npm run build - npm run build-static - name: Deploy uses: s0/git-publish-subdir-action@develop env: diff --git a/.github/workflows/dashboard_pr.yml b/.github/workflows/dashboard_pr.yml index 5df7869e964ea..c7245a2119d99 100644 --- a/.github/workflows/dashboard_pr.yml +++ b/.github/workflows/dashboard_pr.yml @@ -61,4 +61,3 @@ jobs: npm run lint npm run build - npm run build-static diff --git a/Cargo.lock b/Cargo.lock index c0e821669fda0..426b22d9d41d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1904,6 +1904,12 @@ dependencies = [ "winx", ] +[[package]] +name = "cargo-emit" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1582e1c9e755dd6ad6b224dcffb135d199399a4568d454bd89fe515ca8425695" + [[package]] name = "cargo-platform" version = "0.1.3" @@ -3394,6 +3400,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "dircpy" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29259db751c34980bfc44100875890c507f585323453b91936960ab1104272ca" +dependencies = [ + "jwalk", + "log", + "walkdir", +] + [[package]] name = "directories-next" version = "2.0.0" @@ -5497,6 +5514,16 @@ dependencies = [ "simple_asn1", ] +[[package]] +name = "jwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2735847566356cd2179a2a38264839308f7079fa96e6bd5a42d740460e003c56" +dependencies = [ + "crossbeam", + "rayon", +] + [[package]] name = "keyed_priority_queue" version = "0.4.1" @@ -6478,6 +6505,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" +[[package]] +name = "npm_rs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1454347ca3c562570eff8af4a09445783dc4b7ccd00853390a7f88f76037b55" +dependencies = [ + "cfg-if", +] + [[package]] name = "ntapi" version = "0.4.1" @@ -9680,6 +9716,7 @@ dependencies = [ "risingwave_common_heap_profiling", "risingwave_connector", "risingwave_hummock_sdk", + "risingwave_meta_dashboard", "risingwave_meta_model_migration", "risingwave_meta_model_v2", "risingwave_object_store", @@ -9707,6 +9744,27 @@ dependencies = [ "workspace-hack", ] +[[package]] +name = "risingwave_meta_dashboard" +version = "1.7.0-alpha" +dependencies = [ + "anyhow", + "axum", + "bytes", + "cargo-emit", + "dircpy", + "hyper", + "mime_guess", + "npm_rs", + "reqwest", + "rust-embed", + "thiserror-ext", + "tokio", + "tracing", + "tracing-subscriber", + "url", +] + [[package]] name = "risingwave_meta_model_migration" version = "1.7.0-alpha" @@ -10382,6 +10440,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", + "shellexpand 3.1.0", "syn 2.0.48", "walkdir", ] @@ -11195,6 +11254,15 @@ dependencies = [ "dirs", ] +[[package]] +name = "shellexpand" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +dependencies = [ + "dirs", +] + [[package]] name = "shlex" version = "1.3.0" @@ -13672,7 +13740,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "shellexpand", + "shellexpand 2.1.2", "syn 2.0.48", "witx", ] diff --git a/Cargo.toml b/Cargo.toml index 33164cc2de104..f15b17a40e0f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ members = [ "src/java_binding", "src/jni_core", "src/meta", + "src/meta/dashboard", "src/meta/model_v2", "src/meta/model_v2/migration", "src/meta/node", @@ -179,6 +180,7 @@ risingwave_hummock_test = { path = "./src/storage/hummock_test" } risingwave_hummock_trace = { path = "./src/storage/hummock_trace" } risingwave_mem_table_spill_test = { path = "./src/stream/spill_test" } risingwave_meta = { path = "./src/meta" } +risingwave_meta_dashboard = { path = "./src/meta/dashboard" } risingwave_meta_service = { path = "./src/meta/service" } risingwave_meta_model_migration = { path = "src/meta/model_v2/migration" } risingwave_meta_model_v2 = { path = "./src/meta/model_v2" } diff --git a/dashboard/next.config.js b/dashboard/next.config.js index 54b50aa298faf..36c00a6b87905 100644 --- a/dashboard/next.config.js +++ b/dashboard/next.config.js @@ -21,6 +21,11 @@ const nextConfig = { output: "export", trailingSlash: true, + eslint: { + // We have a separate step for running ESLint in CI. + // Ignore to skip the development dependency on `eslint` for production builds. + ignoreDuringBuilds: true, + }, } module.exports = nextConfig diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index c512f41a0afea..10fdd2aaffa88 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -56,7 +56,7 @@ "express": "^4.18.1", "prettier": "^2.7.1", "prettier-plugin-organize-imports": "^3.1.1", - "typescript": "^5.3.3" + "typescript": "5.4.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -10936,9 +10936,9 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -19662,9 +19662,9 @@ } }, "typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true }, "ua-parser-js": { diff --git a/dashboard/package.json b/dashboard/package.json index 1ac15145998dd..08469ef8926bd 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -4,7 +4,6 @@ "dev": "next dev", "build": "next build", "start": "next start", - "build-static": "next build", "gen-proto": "./scripts/generate_proto.sh", "lint": "prettier --check . && next lint", "format": "prettier --write . && next lint --fix", @@ -63,7 +62,7 @@ "express": "^4.18.1", "prettier": "^2.7.1", "prettier-plugin-organize-imports": "^3.1.1", - "typescript": "^5.3.3" + "typescript": "5.4.2" }, "overrides": { "react-json-view": { @@ -75,4 +74,4 @@ "react-dom": "^18.2.0" } } -} \ No newline at end of file +} diff --git a/dashboard/pages/fragment_graph.tsx b/dashboard/pages/fragment_graph.tsx index e72ca7ce3e0ce..f77ab2b5a30e1 100644 --- a/dashboard/pages/fragment_graph.tsx +++ b/dashboard/pages/fragment_graph.tsx @@ -329,7 +329,7 @@ export default function Streaming() { clearInterval(interval) } } - }, [backPressureDataSource]) + }, [backPressureDataSource, toast]) const backPressures = useMemo(() => { if (promethusMetrics || embeddedBackPressureInfo) { diff --git a/docker/Dockerfile b/docker/Dockerfile index d42dc74da3f11..ff6fbba8467e1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -22,7 +22,7 @@ RUN apt-get update && apt-get install -y curl gnupg protobuf-compiler && mkdir - COPY ./dashboard/ /risingwave/dashboard COPY ./proto /risingwave/proto -RUN cd /risingwave/dashboard && npm i && npm run build-static && rm -rf node_modules +RUN cd /risingwave/dashboard && npm i && npm run build && rm -rf node_modules FROM base AS rust-base diff --git a/docker/Dockerfile.hdfs b/docker/Dockerfile.hdfs index d426504b5ccc3..9138214ba47b1 100644 --- a/docker/Dockerfile.hdfs +++ b/docker/Dockerfile.hdfs @@ -23,7 +23,7 @@ RUN apt-get update && apt-get install -y curl gnupg protobuf-compiler && mkdir - COPY ./dashboard/ /risingwave/dashboard COPY ./proto /risingwave/proto -RUN cd /risingwave/dashboard && npm i && npm run build-static && rm -rf node_modules +RUN cd /risingwave/dashboard && npm i && npm run build && rm -rf node_modules FROM base AS java-planner diff --git a/src/meta/Cargo.toml b/src/meta/Cargo.toml index 1008af8e5fef2..07af09d29350d 100644 --- a/src/meta/Cargo.toml +++ b/src/meta/Cargo.toml @@ -53,6 +53,7 @@ risingwave_common = { workspace = true } risingwave_common_heap_profiling = { workspace = true } risingwave_connector = { workspace = true } risingwave_hummock_sdk = { workspace = true } +risingwave_meta_dashboard = { workspace = true } risingwave_meta_model_migration = { workspace = true } risingwave_meta_model_v2 = { workspace = true } risingwave_object_store = { workspace = true } diff --git a/src/meta/dashboard/Cargo.toml b/src/meta/dashboard/Cargo.toml new file mode 100644 index 0000000000000..5edfeb5195e48 --- /dev/null +++ b/src/meta/dashboard/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "risingwave_meta_dashboard" +version = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +keywords = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1" +axum = "0.6" +bytes = "1" +hyper = "0.14" +mime_guess = "2" +reqwest = "0.11" +rust-embed = { version = "8", features = ["interpolate-folder-path", "mime-guess"] } +thiserror-ext = { workspace = true } +tracing = "0.1" +url = "2" + +[dev-dependencies] +tokio = { version = "1", features = ["full"] } +tracing-subscriber = "0.3" + +[build-dependencies] +anyhow = "1" +cargo-emit = "0.2" +dircpy = "0.3" +npm_rs = "1" + +[lints] +workspace = true diff --git a/src/meta/dashboard/build.rs b/src/meta/dashboard/build.rs new file mode 100644 index 0000000000000..5a18ba963adbc --- /dev/null +++ b/src/meta/dashboard/build.rs @@ -0,0 +1,77 @@ +// Copyright 2024 RisingWave Labs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::path::{Path, PathBuf}; + +use cargo_emit::{rerun_if_changed, rustc_cfg}; +use npm_rs::{NodeEnv, NpmEnv}; + +fn env_var_is_true(key: &str) -> bool { + cargo_emit::rerun_if_env_changed!(key); + + std::env::var(key) + .map(|value| { + ["1", "t", "true"] + .iter() + .any(|&s| value.eq_ignore_ascii_case(s)) + }) + .unwrap_or(false) +} + +const DASHBOARD_DIR: &str = "../../../dashboard"; + +fn dest_dir() -> PathBuf { + let out_dir = std::env::var("OUT_DIR").unwrap(); + Path::new(&out_dir).join("assets") +} + +fn build() -> anyhow::Result<()> { + // TODO(bugen): we should include all files and subdirectories under `DASHBOARD_DIR` + // while excluding the `out` directory. There's no elegant way to do this. + rerun_if_changed!(format!("{DASHBOARD_DIR}/components")); + + let exit_status = NpmEnv::default() + .with_node_env(&NodeEnv::Production) + .set_path(DASHBOARD_DIR) + .init_env() + .install(None) + .run("build") + .exec()?; + + if !exit_status.success() { + anyhow::bail!("dashboard build failed with status: {}", exit_status); + } + + let dest = dest_dir(); + let src = Path::new(DASHBOARD_DIR).join("out"); + dircpy::copy_dir(src, dest)?; + + Ok(()) +} + +fn main() -> anyhow::Result<()> { + let should_build = env_var_is_true("ENABLE_BUILD_DASHBOARD"); + + if should_build { + build()?; + // Once build succeeded, set a cfg flag to indicate that the embedded assets + // are ready to be used. + rustc_cfg!("dashboard_built"); + } else { + // If we're not to build, create the destination directory but keep it empty. + std::fs::create_dir_all(dest_dir())?; + } + + Ok(()) +} diff --git a/src/meta/dashboard/examples/serve.rs b/src/meta/dashboard/examples/serve.rs new file mode 100644 index 0000000000000..e72b616b7eb7a --- /dev/null +++ b/src/meta/dashboard/examples/serve.rs @@ -0,0 +1,25 @@ +// Copyright 2024 RisingWave Labs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use risingwave_meta_dashboard::router; + +#[tokio::main] +async fn main() { + tracing_subscriber::fmt::init(); + + axum::Server::bind(&"0.0.0.0:10188".parse().unwrap()) + .serve(router().into_make_service()) + .await + .unwrap(); +} diff --git a/src/meta/dashboard/src/embed.rs b/src/meta/dashboard/src/embed.rs new file mode 100644 index 0000000000000..e38757bd3bac9 --- /dev/null +++ b/src/meta/dashboard/src/embed.rs @@ -0,0 +1,53 @@ +// Copyright 2024 RisingWave Labs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use axum::http::{header, StatusCode, Uri}; +use axum::response::{IntoResponse as _, Response}; +use axum::Router; +use rust_embed::RustEmbed; + +#[derive(RustEmbed)] +#[folder = "$OUT_DIR/assets"] +struct Assets; + +// TODO: switch to `axum-embed` for better robustness after bumping to axum 0.7. +async fn static_handler(uri: Uri) -> Response { + let path = { + if uri.path().ends_with('/') { + // Append `index.html` to directory paths. + format!("{}index.html", uri.path()) + } else { + uri.path().to_owned() + } + }; + let path = path.trim_start_matches('/'); + + match Assets::get(path) { + Some(file) => { + let mime = file.metadata.mimetype(); + + let mut res = file.data.into_response(); + res.headers_mut() + .insert(header::CONTENT_TYPE, mime.parse().unwrap()); + res + } + + None => (StatusCode::NOT_FOUND, "Not Found").into_response(), + } +} + +/// Router for embedded assets. +pub(crate) fn router() -> Router { + Router::new().fallback(static_handler) +} diff --git a/src/meta/dashboard/src/lib.rs b/src/meta/dashboard/src/lib.rs new file mode 100644 index 0000000000000..bb8a9ed5e90e7 --- /dev/null +++ b/src/meta/dashboard/src/lib.rs @@ -0,0 +1,50 @@ +// Copyright 2024 RisingWave Labs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![allow(clippy::doc_markdown)] + +use axum::Router; + +mod embed; +mod proxy; + +/// The router for the dashboard. +/// +/// Based on the configuration, it will either serve the assets embedded in the binary, +/// or proxy all requests to the latest static files built and hosted on GitHub. +/// +/// - If env var `ENABLE_BUILD_DASHBOARD` is not set during the build, the requests to +/// the dashboard will be proxied. This is to reduce the build time and eliminate the +/// dependency on `node`, so that the developer experience can be better. This is the +/// default behavior for CI and development builds. +/// +/// - If env var `ENABLE_BUILD_DASHBOARD` is set during the build, the assets will be +/// built in the build script and embedded in the binary. This is to make the +/// deployment easier and the dashboard more reliable without relying on external or +/// remote resources. This is the default behavior for versioned releases, and can be +/// manually enabled for development builds with RiseDev. +/// +/// If you're going to develop with the dashboard, see `dashboard/README.md` for more +/// details. +pub fn router() -> Router { + // We use `cfg!` instead of `#[cfg]` here to ensure both branches can be checked + // by the compiler no matter which one is actually used. + if cfg!(dashboard_built) { + tracing::info!("using embedded dashboard assets"); + embed::router() + } else { + tracing::info!("using proxied dashboard assets"); + proxy::router() + } +} diff --git a/src/meta/src/dashboard/proxy.rs b/src/meta/dashboard/src/proxy.rs similarity index 77% rename from src/meta/src/dashboard/proxy.rs rename to src/meta/dashboard/src/proxy.rs index 1010a3bb274fa..104ed940dec2f 100644 --- a/src/meta/src/dashboard/proxy.rs +++ b/src/meta/dashboard/src/proxy.rs @@ -13,16 +13,18 @@ // limitations under the License. use std::collections::HashMap; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use anyhow::anyhow; use axum::body::Body; use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; +use axum::Router; use bytes::Bytes; use hyper::header::CONTENT_TYPE; +use hyper::service::service_fn; use hyper::{HeaderMap, Request}; -use parking_lot::Mutex; +use thiserror_ext::AsReport as _; use url::Url; #[derive(Clone)] @@ -60,7 +62,7 @@ impl IntoResponse for CachedResponse { } } -pub async fn proxy( +async fn proxy( req: Request, cache: Arc>>, ) -> anyhow::Result { @@ -69,7 +71,7 @@ pub async fn proxy( path += "index.html"; } - if let Some(resp) = cache.lock().get(&path) { + if let Some(resp) = cache.lock().unwrap().get(&path) { return Ok(resp.clone().into_response()); } @@ -93,7 +95,25 @@ pub async fn proxy( uri: url, }; - cache.lock().insert(path, resp.clone()); + cache.lock().unwrap().insert(path, resp.clone()); Ok(resp.into_response()) } + +/// Router for proxying requests to GitHub static files, requiring internet access. +pub(crate) fn router() -> Router { + let cache = Arc::new(Mutex::new(HashMap::new())); + + Router::new().fallback_service(service_fn(move |req: Request| { + let cache = cache.clone(); + async move { + proxy(req, cache).await.or_else(|err| { + Ok(( + StatusCode::INTERNAL_SERVER_ERROR, + err.context("Unhandled internal error").to_report_string(), + ) + .into_response()) + }) + } + })) +} diff --git a/src/meta/src/dashboard/mod.rs b/src/meta/src/dashboard/mod.rs index 5e5a7476fa10c..2e3848d329d22 100644 --- a/src/meta/src/dashboard/mod.rs +++ b/src/meta/src/dashboard/mod.rs @@ -13,24 +13,19 @@ // limitations under the License. mod prometheus; -mod proxy; -use std::collections::HashMap; use std::net::SocketAddr; use std::path::Path as FilePath; use std::sync::Arc; use anyhow::{anyhow, Result}; -use axum::body::{boxed, Body}; +use axum::body::boxed; use axum::extract::{Extension, Path}; use axum::http::{Method, StatusCode}; use axum::response::{IntoResponse, Response}; use axum::routing::{get, get_service}; use axum::Router; -use hyper::Request; -use parking_lot::Mutex; use risingwave_rpc_client::ComputeClientPool; -use thiserror_ext::AsReport; use tower::{ServiceBuilder, ServiceExt}; use tower_http::add_extension::AddExtensionLayer; use tower_http::compression::CompressionLayer; @@ -416,26 +411,13 @@ impl DashboardService { .layer(cors_layer); let trace_ui_router = otlp_embedded::ui_app(srv.trace_state.clone(), "/trace/"); - let dashboard_router = if let Some(ui_path) = ui_path { + // TODO(bugen): remove `ui_path` and all in the embedded `risingwave_meta_dashboard`. get_service(ServeDir::new(ui_path)) .handle_error(|e| async move { match e {} }) .boxed_clone() } else { - let cache = Arc::new(Mutex::new(HashMap::new())); - tower::service_fn(move |req: Request| { - let cache = cache.clone(); - async move { - proxy::proxy(req, cache).await.or_else(|err| { - Ok(( - StatusCode::INTERNAL_SERVER_ERROR, - err.context("Unhandled internal error").to_report_string(), - ) - .into_response()) - }) - } - }) - .boxed_clone() + risingwave_meta_dashboard::router().boxed_clone() }; let app = Router::new() diff --git a/src/workspace-hack/Cargo.toml b/src/workspace-hack/Cargo.toml index bd33f5268aedb..efa6078ba3eec 100644 --- a/src/workspace-hack/Cargo.toml +++ b/src/workspace-hack/Cargo.toml @@ -168,6 +168,9 @@ auto_enums = { version = "0.8", features = ["futures03", "tokio1"] } bitflags = { version = "2", default-features = false, features = ["serde", "std"] } bytes = { version = "1", features = ["serde"] } cc = { version = "1", default-features = false, features = ["parallel"] } +crossbeam-epoch = { version = "0.9" } +crossbeam-queue = { version = "0.3" } +crossbeam-utils = { version = "0.8" } deranged = { version = "0.3", default-features = false, features = ["powerfmt", "serde", "std"] } digest = { version = "0.10", features = ["mac", "oid", "std"] } either = { version = "1", features = ["serde"] } @@ -200,6 +203,7 @@ regex-automata = { version = "0.4", default-features = false, features = ["dfa", regex-syntax = { version = "0.8" } rustc-hash = { version = "1" } rustix = { version = "0.38", features = ["fs", "net"] } +scopeguard = { version = "1" } serde = { version = "1", features = ["alloc", "derive", "rc"] } serde_json = { version = "1", features = ["alloc", "raw_value"] } sha2 = { version = "0.10", features = ["oid"] }