use std::sync::Mutex;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PageState {
Ready,
Busy,
Error,
}
#[derive(Debug)]
pub struct PageInfo {
pub page_index: usize,
pub state: PageState,
pub url: String,
}
impl PageInfo {
pub fn new(page_index: usize) -> Self {
Self {
page_index,
state: PageState::Ready,
url: String::new(),
}
}
}
pub struct PagePool {
pub max_pages: u32,
pages: Mutex<Vec<PageInfo>>,
}
impl PagePool {
pub fn new(max_pages: u32) -> Self {
Self {
max_pages,
pages: Mutex::new(Vec::new()),
}
}
pub fn add_page(&self, page_index: usize) -> crate::error::Result<()> {
let mut pages = self.pages.lock().unwrap();
if pages.len() >= self.max_pages as usize {
return Err(crate::error::BrowserError::PagePool(format!(
"page pool full ({}/{})",
pages.len(),
self.max_pages
)));
}
pages.push(PageInfo::new(page_index));
Ok(())
}
fn with_page(&self, page_index: usize, f: impl FnOnce(&mut PageInfo)) {
let mut pages = self.pages.lock().unwrap();
if let Some(info) = pages.iter_mut().find(|p| p.page_index == page_index) {
f(info);
}
}
pub fn mark_busy(&self, page_index: usize, url: &str) {
self.with_page(page_index, |info| {
info.state = PageState::Busy;
info.url = url.to_owned();
});
}
pub fn mark_ready(&self, page_index: usize) {
self.with_page(page_index, |info| info.state = PageState::Ready);
}
pub fn mark_error(&self, page_index: usize) {
self.with_page(page_index, |info| info.state = PageState::Error);
}
pub fn pages_count(&self) -> usize {
self.pages.lock().unwrap().len()
}
pub fn busy_count(&self) -> usize {
self.pages
.lock()
.unwrap()
.iter()
.filter(|p| p.state == PageState::Busy)
.count()
}
pub fn cleanup_error_pages(&self) {
self.pages
.lock()
.unwrap()
.retain(|p| p.state != PageState::Error);
}
pub fn stats(&self) -> PoolStats {
let pages = self.pages.lock().unwrap();
PoolStats {
total_pages: pages.len(),
busy_pages: pages.iter().filter(|p| p.state == PageState::Busy).count(),
max_pages: self.max_pages as usize,
}
}
}
#[derive(Debug, Clone)]
pub struct PoolStats {
pub total_pages: usize,
pub busy_pages: usize,
pub max_pages: usize,
}