pub(crate) fn load_routes(
        &self,
        cache_config_path: String,
        module_cache_dir: PathBuf,
    ) -> Result<Vec<RouteEntry>, anyhow::Error> {
        let start_time = Instant::now();

        let prefix = self
            .route
            .strip_suffix("/...")
            .unwrap_or(self.route.as_str());
        let mut routes = vec![];

        routes.push(RouteEntry {
            path: self.route.to_owned(), // We don't use prefix because prefix has been normalized.
            entrypoint: self.entrypoint.clone().unwrap_or("_start".to_string()),
        });

        let store = self.new_store(cache_config_path)?;
        let mut linker = Linker::new(&store);
        let stdout_buf: Vec<u8> = vec![];
        let stdout_mutex = Arc::new(RwLock::new(stdout_buf));
        let stdout = WritePipe::from_shared(stdout_mutex.clone());
        let mut builder = WasiCtxBuilder::new();

        builder = builder
            .inherit_stderr() // STDERR goes to the console of the server
            .stdout(Box::new(stdout));

        let ctx = builder.build()?;
        let wasi = Wasi::new(&store, ctx);
        wasi.add_to_linker(&mut linker)?;
        let http = wasi_experimental_http_wasmtime::HttpCtx::new(None, None)?;
        http.add_to_linker(&mut linker)?;

        let module = self.load_cached_module(&store, module_cache_dir)?;
        let instance = linker.instantiate(&module)?;

        let duration = start_time.elapsed();
        log::info!(
            "(load_routes) instantiation time for module {}: {:#?}",
            self.module.as_str(),
            duration
        );

        match instance.get_func("_routes") {
            Some(func) => {
                func.call(&[])?;
            }
            None => return Ok(routes),
        }

        let out = stdout_mutex.read().unwrap();
        out.lines().for_each(|line_result| {
            if let Ok(line) = line_result {
                // Split line into parts
                let parts: Vec<&str> = line.trim().split_whitespace().collect();

                if parts.is_empty() {
                    return;
                }

                let key = parts.get(0).unwrap_or(&"/").to_string();
                let val = parts.get(1).unwrap_or(&"_start").to_string();
                routes.push(RouteEntry {
                    path: format!("{}{}", prefix, key),
                    entrypoint: val,
                });
            }
        });
        // We reverse the routes so that the top-level routes are evaluated last.
        // This gives a predictable order for traversing routes. Because the base path
        // is the last one evaluated, if the base path is /..., it will match when no
        // other more specific route lasts.
        //
        // Additionally, when Wasm authors create their _routes() callback, they can
        // organize their outputs to match according to their own precedence merely by
        // putting the higher precedence routes at the end of the output.
        routes.reverse();
        Ok(routes)
    }
/// Examine the given module to see if it has any routes.
///
/// If it has any routes, add them to the vector and return it.
Examine the given module to see if it has any routes.
If it has any routes, add them to the vector and return it.
Examine the given module to see if it has any routes . If it has any routes add them to the vector and return it .
pub(crate) fn load_routes(
        &self,
        cache_config_path: String,
        module_cache_dir: PathBuf,
    ) -> Result<Vec<RouteEntry>, anyhow::Error> {
        let start_time = Instant::now();
        let prefix = self
            .route
            .strip_suffix("/...")
            .unwrap_or(self.route.as_str());
        let mut routes = vec![];
        routes.push(RouteEntry {
            path: self.route.to_owned(), // We don't use prefix because prefix has been normalized.
            entrypoint: self.entrypoint.clone().unwrap_or("_start".to_string()),
        });
        let store = self.new_store(cache_config_path)?;
        let mut linker = Linker::new(&store);
        let stdout_buf: Vec<u8> = vec![];
        let stdout_mutex = Arc::new(RwLock::new(stdout_buf));
        let stdout = WritePipe::from_shared(stdout_mutex.clone());
        let mut builder = WasiCtxBuilder::new();
        builder = builder
            .inherit_stderr() // STDERR goes to the console of the server
            .stdout(Box::new(stdout));
        let ctx = builder.build()?;
        let wasi = Wasi::new(&store, ctx);
        wasi.add_to_linker(&mut linker)?;
        let http = wasi_experimental_http_wasmtime::HttpCtx::new(None, None)?;
        http.add_to_linker(&mut linker)?;
        let module = self.load_cached_module(&store, module_cache_dir)?;
        let instance = linker.instantiate(&module)?;
        let duration = start_time.elapsed();
        log::info!(
            "(load_routes) instantiation time for module {}: {:#?}",
            self.module.as_str(),
            duration
        );
        match instance.get_func("_routes") {
            Some(func) => {
                func.call(&[])?;
            }
            None => return Ok(routes),
        }
        let out = stdout_mutex.read().unwrap();
        out.lines().for_each(|line_result| {
            if let Ok(line) = line_result {
                // Split line into parts
                let parts: Vec<&str> = line.trim().split_whitespace().collect();
                if parts.is_empty() {
                    return;
                }
                let key = parts.get(0).unwrap_or(&"/").to_string();
                let val = parts.get(1).unwrap_or(&"_start").to_string();
                routes.push(RouteEntry {
                    path: format!("{}{}", prefix, key),
                    entrypoint: val,
                });
            }
        });
        // We reverse the routes so that the top-level routes are evaluated last.
        // This gives a predictable order for traversing routes. Because the base path
        // is the last one evaluated, if the base path is /..., it will match when no
        // other more specific route lasts.
        //
        // Additionally, when Wasm authors create their _routes() callback, they can
        // organize their outputs to match according to their own precedence merely by
        // putting the higher precedence routes at the end of the output.
        routes.reverse();
        Ok(routes)
    }
pub ( crate ) fn load_routes ( & self , cache_config_path : String , module_cache_dir : PathBuf , ) -> Result < Vec < RouteEntry > , anyhow :: Error > { let start_time = Instant :: now ( ) ; let prefix = self . route . strip_suffix ( " " ) . unwrap_or ( self . route . as_str ( ) ) ; let mut routes = vec ! [ ] ; routes . push ( RouteEntry { path : self . route . to_owned ( ) , // We don't use prefix because prefix has been normalized. entrypoint : self . entrypoint . clone ( ) . unwrap_or ( " " . to_string ( ) ) , } ) ; let store = self . new_store ( cache_config_path ) ? ; let mut linker = Linker :: new ( & store ) ; let stdout_buf : Vec < u8 > = vec ! [ ] ; let stdout_mutex = Arc :: new ( RwLock :: new ( stdout_buf ) ) ; let stdout = WritePipe :: from_shared ( stdout_mutex . clone ( ) ) ; let mut builder = WasiCtxBuilder :: new ( ) ; builder = builder . inherit_stderr ( ) // STDERR goes to the console of the server . stdout ( Box :: new ( stdout ) ) ; let ctx = builder . build ( ) ? ; let wasi = Wasi :: new ( & store , ctx ) ; wasi . add_to_linker ( & mut linker ) ? ; let http = wasi_experimental_http_wasmtime :: HttpCtx :: new ( None , None ) ? ; http . add_to_linker ( & mut linker ) ? ; let module = self . load_cached_module ( & store , module_cache_dir ) ? ; let instance = linker . instantiate ( & module ) ? ; let duration = start_time . elapsed ( ) ; log :: info ! ( " " self module as_str ( ) duration ) ; match instance . get_func ( " " ) { Some ( func ) => { func . call ( & [ ] ) ? ; } None => return Ok ( routes ) , } let out = stdout_mutex . read ( ) . unwrap ( ) ; out . lines ( ) . for_each ( | line_result | { if let Ok ( line ) = line_result { // Split line into parts let parts : Vec < & str > = line . trim ( ) . split_whitespace ( ) . collect ( ) ; if parts . is_empty ( ) { return ; } let key = parts . get ( 0 ) . unwrap_or ( & " " ) . to_string ( ) ; let val = parts . get ( 1 ) . unwrap_or ( & " " ) . to_string ( ) ; routes . push ( RouteEntry { path : format ! ( " " prefix key ) , entrypoint : val , } ) ; } } ) ; // We reverse the routes so that the top-level routes are evaluated last. // This gives a predictable order for traversing routes. Because the base path // is the last one evaluated, if the base path is /..., it will match when no // other more specific route lasts. // // Additionally, when Wasm authors create their _routes() callback, they can // organize their outputs to match according to their own precedence merely by // putting the higher precedence routes at the end of the output. routes . reverse ( ) ; Ok ( routes ) }
Examine the given module to see if it has any routes.
Examine the given module to see if it has any routes .
&self
cache_config_path
String
module_cache_dir
PathBuf