use std::collections::{HashMap, HashSet};
use std::sync::{Arc, Mutex, RwLock};
use std::time::{Duration, Instant};
pub struct LazyWebAPI {
initialized_apis: Arc<RwLock<HashSet<String>>>,
initialization_queue: Arc<Mutex<Vec<ApiInitTask>>>,
init_semaphore: Arc<Semaphore>,
stats: Arc<Mutex<LazyInitStats>>,
}
#[derive(Debug, Clone)]
struct ApiInitTask {
name: String,
priority: u8,
created_at: Instant,
}
impl ApiInitTask {
fn new(name: String) -> Self {
Self {
name,
priority: 5, created_at: Instant::now(),
}
}
fn with_priority(name: String, priority: u8) -> Self {
Self {
name,
priority,
created_at: Instant::now(),
}
}
}
#[derive(Debug, Clone, Default)]
pub struct LazyInitStats {
pub total_initializations: u64,
pub successful_initializations: u64,
pub failed_initializations: u64,
pub total_init_time_ms: u64,
pub cache_hits: u64,
pub cache_misses: u64,
}
impl LazyWebAPI {
pub fn new() -> Self {
Self {
initialized_apis: Arc::new(Mutex::new(HashSet::new())),
initialization_queue: Arc::new(Mutex::new(Vec::new())),
init_semaphore: Arc::new(Mutex::new(Semaphore::new(10))), stats: Arc::new(Mutex::new(LazyInitStats::default())),
}
}
pub async fn is_initialized(&self, api_name: &str) -> bool {
let initialized: _ = self.initialized_apis.read().await;
initialized.contains(api_name)
}
pub async fn init_on_demand(&self, api_name: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
if self.is_initialized(api_name).await {
let mut stats = self.stats.lock().unwrap();
stats.cache_hits += 1;
return Ok(());
}
let mut stats = self.stats.lock().unwrap();
stats.total_initializations += 1;
stats.cache_misses += 1;
drop(stats);
let _permit: _ = self.init_semaphore.acquire().await.map_err(|_| "Failed to acquire semaphore")?;
if self.is_initialized(api_name).await {
return Ok(());
}
let start: _ = Instant::now();
self.perform_initialization(api_name).await?;
let elapsed: _ = start.elapsed();
let mut stats = self.stats.lock().unwrap();
stats.successful_initializations += 1;
stats.total_init_time_ms += elapsed.as_millis() as u64;
Ok(())
}
async fn perform_initialization(&self, api_name: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
tokio::time::sleep(Duration::from_micros(100)).await;
let mut initialized = self.initialized_apis.write().await;
initialized.insert(api_name.to_string());
Ok(())
}
pub async fn init_multiple(&self, apis: &[&str]) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let mut tasks: Vec<String> = Vec::new();
for &api in apis {
if !self.is_initialized(api).await {
let api: _ = api.to_string();
let init_result: _ = self.init_on_demand(&api).await;
if let Err(e) = init_result {
return Err(e);
}
}
}
Ok(())
}
pub fn get_stats(&self) -> LazyInitStats {
self.stats.lock().unwrap().clone()
}
pub fn reset_stats(&self) {
let mut stats = self.stats.lock().unwrap();
*stats = LazyInitStats::default();
}
}
impl Default for LazyWebAPI {
fn default() -> Self {
Self::new()
}
}
pub struct LazyInitializer<T> {
init_fn: Arc<dyn Fn() -> Result<T, Box<dyn std::error::Error + Send + Sync>> + Send + Sync>,
value: Arc<Mutex<Option<T>>>,
initialized: Arc<Mutex<bool>>,
stats: Arc<Mutex<InitStats>>,
}
#[derive(Debug, Clone)]
pub struct InitStats {
pub initialization_count: u64,
pub total_init_time: Duration,
pub last_init_time: Option<Duration>,
}
impl InitStats {
pub fn new() -> Self {
Self {
initialization_count: 0,
total_init_time: Duration::from_nanos(0),
last_init_time: None,
}
}
}
impl Default for InitStats {
fn default() -> Self {
Self::new()
}
}
impl<T> LazyInitializer<T> {
pub fn new<F>(init_fn: F) -> Self
where
F: Fn() -> Result<T, Box<dyn std::error::Error + Send + Sync>> + Send + Sync + 'static,
{
Self {
init_fn: Arc::new(Mutex::new(init_fn)),
value: Arc::new(Mutex::new(None)),
initialized: Arc::new(Mutex::new(false)),
stats: Arc::new(Mutex::new(InitStats::new())),
}
}
pub async fn get(&self) -> Result<T, Box<dyn std::error::Error + Send + Sync>>
where
T: Clone,
{
{
let initialized: _ = self.initialized.lock().unwrap();
if *initialized {
let value: _ = self.value.lock().unwrap();
if let Some(ref val) = *value {
return Ok(val.clone());
}
}
}
let start: _ = Instant::now();
let init_fn: _ = self.init_fn.clone();
let result: _ = init_fn()?;
let elapsed: _ = start.elapsed();
{
let mut value = self.value.lock().unwrap();
*value = Some(result.clone());
}
{
let mut initialized = self.initialized.lock().unwrap();
*initialized = true;
}
{
let mut stats = self.stats.lock().unwrap();
stats.initialization_count += 1;
stats.total_init_time += elapsed;
stats.last_init_time = Some(elapsed);
}
Ok(result)
}
pub async fn reinit(&self) -> Result<T, Box<dyn std::error::Error + Send + Sync>>
where
T: Clone,
{
{
let mut initialized = self.initialized.lock().unwrap();
*initialized = false;
}
{
let mut value = self.value.lock().unwrap();
*value = None;
}
self.get().await
}
pub fn get_stats(&self) -> InitStats {
self.stats.lock().unwrap().clone()
}
pub fn is_initialized(&self) -> bool {
*self.initialized.lock().unwrap()
}
}
pub struct OnDemandLoader {
loaded_modules: Arc<RwLock<HashMap<String, LoadedModule>>>,
module_factory: Arc<dyn ModuleFactory + Send + Sync>,
stats: Arc<Mutex<LoaderStats>>,
}
#[derive(Debug, Clone)]
struct LoadedModule {
data: Vec<u8>,
load_time: Instant,
access_count: u64,
}
pub trait ModuleFactory {
fn create_module(&self, name: &str) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>>;
}
pub struct SimpleModuleFactory;
impl ModuleFactory for SimpleModuleFactory {
fn create_module(&self, name: &str) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> {
let module_data: _ = format!("// Module: {}\nconsole.log('{} loaded');", name, name);
Ok(module_data.into_bytes())
}
}
#[derive(Debug, Clone, Default)]
pub struct LoaderStats {
pub total_loads: u64,
pub successful_loads: u64,
pub failed_loads: u64,
pub total_load_time_ms: u64,
pub cache_hits: u64,
pub cache_misses: u64,
}
impl OnDemandLoader {
pub fn new() -> Self {
Self::with_factory(Box::new(SimpleModuleFactory))
}
pub fn with_factory(factory: Box<dyn ModuleFactory + Send + Sync>) -> Self {
Self {
loaded_modules: Arc::new(Mutex::new(HashMap::new())),
module_factory: Arc::from(factory),
stats: Arc::new(Mutex::new(LoaderStats::default())),
}
}
pub async fn load_module(&self, name: &str) -> Result<Option<Vec<u8>, Box<dyn std::error::Error + Send + Sync>>> {
let module_data: _ = {
let modules: _ = self.loaded_modules.read().await;
modules.get(name).map(|module| module.data.clone())
};
if let Some(data) = module_data {
let mut stats = self.stats.lock().unwrap();
stats.cache_hits += 1;
let mut modules = self.loaded_modules.write().await;
if let Some(module) = modules.get_mut(name) {
module.access_count += 1;
}
return Ok(Some(data));
}
let mut stats = self.stats.lock().unwrap();
stats.total_loads += 1;
stats.cache_misses += 1;
drop(stats);
let start: _ = Instant::now();
let data: _ = self.module_factory.create_module(name)?;
let elapsed: _ = start.elapsed();
{
let mut modules = self.loaded_modules.write().await;
modules.insert(
name.to_string(),
LoadedModule {
data: data.clone(),
load_time: Instant::now(),
access_count: 1,
},
);
}
let mut stats = self.stats.lock().unwrap();
stats.successful_loads += 1;
stats.total_load_time_ms += elapsed.as_millis() as u64;
Ok(Some(data))
}
pub fn get_stats(&self) -> LoaderStats {
self.stats.lock().unwrap().clone()
}
pub async fn cleanup_unused(&self, max_age: Duration) -> usize {
let mut modules = self.loaded_modules.write().await;
let now: _ = Instant::now();
let mut removed = 0;
modules.retain(|_, module| {
if now.duration_since(module.load_time) > max_age && module.access_count == 0 {
removed += 1;
false
} else {
true
}
});
removed
}
}
impl Default for OnDemandLoader {
fn default() -> Self {
Self::new()
}
}
pub struct StartupOptimizer {
lazy_web_api: Arc<LazyWebAPI>,
on_demand_loader: Arc<OnDemandLoader>,
startup_time: Arc<Mutex<Option<Instant>>>,
optimization_level: OptimizationLevel,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum OptimizationLevel {
None,
Basic,
Aggressive,
Maximum,
}
impl StartupOptimizer {
pub fn new(level: OptimizationLevel) -> Self {
Self {
lazy_web_api: Arc::new(Mutex::new(LazyWebAPI::new())),
on_demand_loader: Arc::new(Mutex::new(OnDemandLoader::new())),
startup_time: Arc::new(Mutex::new(None)),
optimization_level: level,
}
}
pub fn start_optimization(&self) {
let mut startup_time = self.startup_time.lock().unwrap();
*startup_time = Some(Instant::now());
}
pub fn get_startup_time(&self) -> Option<Duration> {
let startup_time: _ = self.startup_time.lock().unwrap();
startup_time.map(|start| start.elapsed())
}
pub fn get_lazy_web_api(&self) -> Arc<LazyWebAPI> {
self.lazy_web_api.clone()
}
pub fn get_on_demand_loader(&self) -> Arc<OnDemandLoader> {
self.on_demand_loader.clone()
}
pub async fn perform_pre_optimization(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
match self.optimization_level {
OptimizationLevel::None => {}
OptimizationLevel::Basic => {
self.lazy_web_api.init_multiple(&["console", "process"]).await?;
}
OptimizationLevel::Aggressive => {
let apis: _ = &["console", "process", "path", "util", "buffer"];
self.lazy_web_api.init_multiple(apis).await?;
}
OptimizationLevel::Maximum => {
let apis: _ = &["console", "process", "path", "util", "buffer", "fs", "os", "url"];
self.lazy_web_api.init_multiple(apis).await?;
let modules: _ = &["util", "buffer", "events", "stream"];
for &module in modules {
let _: _ = self.on_demand_loader.load_module(module).await;
}
}
}
Ok(())
}
}
impl Default for StartupOptimizer {
fn default() -> Self {
Self::new(OptimizationLevel::Aggressive)
}
}