From 4f5d6378419231dbe79744eda8e710355b560462 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Wed, 5 Apr 2023 18:31:07 +0530 Subject: [PATCH] chore(cli/bench): add ws echo bench (#18595) --- cli/bench/http.rs | 2 +- cli/bench/main.rs | 8 ++++ cli/bench/websocket.rs | 77 ++++++++++++++++++++++++++++++++ cli/bench/websocket/deno_echo.js | 25 +++++++++++ third_party | 2 +- 5 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 cli/bench/websocket.rs create mode 100644 cli/bench/websocket/deno_echo.js diff --git a/cli/bench/http.rs b/cli/bench/http.rs index 065d6f6571..4f8ab968ff 100644 --- a/cli/bench/http.rs +++ b/cli/bench/http.rs @@ -187,7 +187,7 @@ fn run( } static NEXT_PORT: AtomicU16 = AtomicU16::new(4544); -fn get_port() -> u16 { +pub(crate) fn get_port() -> u16 { let p = NEXT_PORT.load(Ordering::SeqCst); NEXT_PORT.store(p.wrapping_add(1), Ordering::SeqCst); p diff --git a/cli/bench/main.rs b/cli/bench/main.rs index 48598a9b0b..721cf06ab2 100644 --- a/cli/bench/main.rs +++ b/cli/bench/main.rs @@ -17,6 +17,7 @@ include!("../util/time.rs"); mod http; mod lsp; +mod websocket; fn read_json(filename: &str) -> Result { let f = fs::File::open(filename)?; @@ -401,6 +402,7 @@ struct BenchResult { max_memory: HashMap, lsp_exec_time: HashMap, req_per_sec: HashMap, + ws_msg_per_sec: HashMap, syscall_count: HashMap, thread_count: HashMap, } @@ -416,6 +418,7 @@ async fn main() -> Result<()> { "cargo_deps", "lsp", "http", + "websocket", "strace", "mem_usage", ]; @@ -455,6 +458,11 @@ async fn main() -> Result<()> { ..Default::default() }; + if benchmarks.contains(&"websocket") { + let ws = websocket::benchmark()?; + new_data.ws_msg_per_sec = ws; + } + if benchmarks.contains(&"bundle") { let bundle_size = bundle_benchmark(&deno_exe)?; new_data.bundle_size = bundle_size; diff --git a/cli/bench/websocket.rs b/cli/bench/websocket.rs new file mode 100644 index 0000000000..84a7996603 --- /dev/null +++ b/cli/bench/websocket.rs @@ -0,0 +1,77 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +use std::collections::HashMap; +use std::io::BufRead; +use std::path::Path; +use std::process::Command; +use std::process::Stdio; +use std::time::Duration; + +use super::Result; + +pub fn benchmark() -> Result> { + let deno_exe = test_util::deno_exe_path(); + let deno_exe = deno_exe.to_str().unwrap(); + + let mut res = HashMap::new(); + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + let ws_dir = manifest_dir.join("bench").join("websocket"); + for entry in std::fs::read_dir(&ws_dir)? { + let port = crate::http::get_port(); + let entry = entry?; + let pathbuf = entry.path(); + let path = pathbuf.to_str().unwrap(); + let file_stem = pathbuf.file_stem().unwrap().to_str().unwrap(); + + let mut cmd = Command::new(deno_exe); + let mut server = cmd + .arg("run") + .arg("-A") + .arg("--unstable") + .arg(path) + .arg(&port.to_string()) + .spawn() + .unwrap(); + + std::thread::sleep(Duration::from_secs(5)); // wait for server to wake up. + + let load_test = test_util::prebuilt_tool_path("load_test"); + assert!(load_test.is_file()); + // ./load_test 100 0.0.0.0 8000 0 0 + // Running benchmark now... + // Msg/sec: 161327.500000 + // Msg/sec: 163977.000000 + // ^C⏎ + let mut cmd = Command::new(load_test); + let mut process = cmd + .stdout(Stdio::piped()) + .arg("100") + .arg("0.0.0.0") + .arg(&port.to_string()) + .arg("0") + .arg("0") + .spawn() + .unwrap(); + + let mut lines = Vec::new(); + + let mut stdout = + std::io::BufReader::new(process.stdout.take().unwrap()).lines(); + for _ in 0..5 { + let line = stdout.next().unwrap().unwrap(); + lines.push(line); + } + + process.kill().unwrap(); + let msg_per_sec = lines + .into_iter() + .filter(|line| line.starts_with("Msg/sec:")) + .map(|line| line.split(": ").nth(1).unwrap().parse::().unwrap()) + .max_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap(); + + res.insert(file_stem.to_string(), msg_per_sec); + server.kill().unwrap(); + } + + Ok(res) +} diff --git a/cli/bench/websocket/deno_echo.js b/cli/bench/websocket/deno_echo.js new file mode 100644 index 0000000000..70e64dcbe5 --- /dev/null +++ b/cli/bench/websocket/deno_echo.js @@ -0,0 +1,25 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. + +const port = Deno.args[0] ?? "8080"; +const { serve } = Deno; + +function handler(request) { + const { socket, response } = Deno.upgradeWebSocket(request, { + idleTimeout: 0, + }); + socket.onmessage = (e) => { + socket.send(e.data); + }; + + socket.onopen = () => { + console.log("Connected to client"); + }; + + socket.onerror = (e) => { + console.log(e); + }; + + return response; +} + +serve(handler, { port: parseInt(port), hostname: "0.0.0.0" }); diff --git a/third_party b/third_party index 17882602ab..fef5eaa2e3 160000 --- a/third_party +++ b/third_party @@ -1 +1 @@ -Subproject commit 17882602ab09dbda744f903a07e28ceab038dac9 +Subproject commit fef5eaa2e364db431cfbf8089afdd81f71fd46d2