#[cfg(all(feature = "url-ingestion", feature = "tokio-runtime", not(target_arch = "wasm32")))]
use crawlberg::{CrawlConfig, CrawlEngine};
#[cfg(all(feature = "url-ingestion", feature = "tokio-runtime", not(target_arch = "wasm32")))]
use crate::Result;
#[cfg(all(feature = "url-ingestion", feature = "tokio-runtime", not(target_arch = "wasm32")))]
use crate::engine::EngineInner;
#[cfg(all(feature = "url-ingestion", feature = "tokio-runtime", not(target_arch = "wasm32")))]
use crate::engine::extract_impl::map_crawl_error;
#[cfg(all(feature = "url-ingestion", feature = "tokio-runtime", not(target_arch = "wasm32")))]
pub(crate) struct CrawlHandleMemo {
fingerprint: u64,
engine: CrawlEngine,
}
#[cfg(all(feature = "url-ingestion", feature = "tokio-runtime", not(target_arch = "wasm32")))]
pub(crate) fn crawl_fingerprint(config: &CrawlConfig) -> u64 {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hasher = DefaultHasher::new();
match serde_json::to_vec(config) {
Ok(bytes) => bytes.hash(&mut hasher),
Err(_) => format!("{config:?}").hash(&mut hasher),
}
hasher.finish()
}
#[cfg(all(feature = "url-ingestion", feature = "tokio-runtime", not(target_arch = "wasm32")))]
impl EngineInner {
pub(crate) fn crawl_engine_for(&self, config: &CrawlConfig) -> Result<CrawlEngine> {
let fingerprint = crawl_fingerprint(config);
let mut guard = self.crawl.lock();
if let Some(memo) = guard.as_ref()
&& memo.fingerprint == fingerprint
{
return Ok(memo.engine.clone());
}
config.validate().map_err(map_crawl_error)?;
let engine = CrawlEngine::builder()
.config(config.clone())
.build()
.map_err(map_crawl_error)?;
*guard = Some(CrawlHandleMemo {
fingerprint,
engine: engine.clone(),
});
Ok(engine)
}
}