Skip to content

Commit 45333f8

Browse files
committedJul 2, 2024
feat: Refactor code to utilize tab pooling for improved performance
- Added `use headless_chrome::Tab` and `use std::collections::VecDeque` to import necessary structs - Modified `args` in `main` function to include new command line arguments - Refactored `with_browser` and `with_semaphore` functions to use cloned objects instead of references - Added `with_tab_pool` function to handle tab pool using a mutex and vector deque - Modified `render_handler` function to reuse tabs from the tab pool
1 parent 3b12506 commit 45333f8

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed
 

‎src/main.rs

+35-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
use headless_chrome::{Browser, LaunchOptions};
2-
use serde::Deserialize;
1+
use headless_chrome::{Browser, LaunchOptions, Tab};
32
use std::sync::Arc;
4-
use tokio::sync::Semaphore;
5-
use warp::Filter;
63
use std::ffi::OsStr;
4+
use tokio::sync::{Semaphore, Mutex};
5+
use warp::Filter;
6+
use serde::Deserialize;
7+
use std::collections::VecDeque;
78

89
#[tokio::main]
910
async fn main() {
1011
let args: Vec<&OsStr> = vec![
1112
OsStr::new("--no-sandbox"),
1213
OsStr::new("--disable-gpu"),
13-
OsStr::new("--ignore-certificate-errors"),
14+
OsStr::new("--disable-dev-shm-usage"),
15+
OsStr::new("--remote-debugging-port=9222"),
16+
OsStr::new("--headless"),
1417
];
1518

1619
let browser = Arc::new(
@@ -23,11 +26,13 @@ async fn main() {
2326
);
2427

2528
let semaphore = Arc::new(Semaphore::new(4));
29+
let tab_pool = Arc::new(Mutex::new(VecDeque::new()));
2630

2731
let render_route = warp::path("html")
2832
.and(warp::query::<RenderQuery>())
29-
.and(with_browser(browser))
30-
.and(with_semaphore(semaphore))
33+
.and(with_browser(browser.clone()))
34+
.and(with_semaphore(semaphore.clone()))
35+
.and(with_tab_pool(tab_pool.clone()))
3136
.and_then(render_handler);
3237

3338
println!("Server running on http://0.0.0.0:8080");
@@ -51,6 +56,12 @@ fn with_semaphore(
5156
warp::any().map(move || semaphore.clone())
5257
}
5358

59+
fn with_tab_pool(
60+
tab_pool: Arc<Mutex<VecDeque<Arc<Tab>>>>,
61+
) -> impl Filter<Extract = (Arc<Mutex<VecDeque<Arc<Tab>>>>,), Error = std::convert::Infallible> + Clone {
62+
warp::any().map(move || tab_pool.clone())
63+
}
64+
5465
#[derive(Debug)]
5566
struct CustomError;
5667

@@ -60,13 +71,21 @@ async fn render_handler(
6071
query: RenderQuery,
6172
browser: Arc<Browser>,
6273
semaphore: Arc<Semaphore>,
74+
tab_pool: Arc<Mutex<VecDeque<Arc<Tab>>>>,
6375
) -> Result<impl warp::Reply, warp::Rejection> {
6476
let _permit = semaphore.acquire().await;
6577

66-
let tab = browser.new_tab().map_err(|e| {
67-
eprintln!("Failed to create new tab: {:?}", e);
68-
warp::reject::custom(CustomError)
69-
})?;
78+
let tab = {
79+
let mut pool = tab_pool.lock().await;
80+
if let Some(tab) = pool.pop_front() {
81+
tab
82+
} else {
83+
browser.new_tab().map_err(|e| {
84+
eprintln!("Failed to create new tab: {:?}", e);
85+
warp::reject::custom(CustomError)
86+
})?
87+
}
88+
};
7089

7190
tab.navigate_to(&query.url).map_err(|e| {
7291
eprintln!("Failed to navigate to URL: {:?}", e);
@@ -82,5 +101,10 @@ async fn render_handler(
82101
warp::reject::custom(CustomError)
83102
})?;
84103

104+
{
105+
let mut pool = tab_pool.lock().await;
106+
pool.push_back(Arc::clone(&tab));
107+
}
108+
85109
Ok(warp::reply::html(content))
86110
}

0 commit comments

Comments
 (0)