use crate::{config::EdgeFunctionComponents, context::ComponentsContext};
use wasmtime::{component::Linker, Engine, Store};
use crate::context::HostState;
use crate::edge_function::versions::v1_0_0::edge_function::EdgeFunctionV100;
use crate::edge_function::versions::v1_0_0::edge_function::EdgeFunctionV100Pre;
pub mod edge_function {
wasmtime::component::bindgen!({
path: "src/edge_function/wit",
world: "edge-function-v100",
imports: {
default: tracing | trappable,
},
exports: {
default: async,
},
require_store_data_send: true,
with: {
"wasi:http/types/outgoing-body": wasmtime_wasi_http::body::HostOutgoingBody,
"wasi:http/types/future-incoming-response": wasmtime_wasi_http::types::HostFutureIncomingResponse,
"wasi:http/types/outgoing-response": wasmtime_wasi_http::types::HostOutgoingResponse,
"wasi:http/types/future-trailers": wasmtime_wasi_http::body::HostFutureTrailers,
"wasi:http/types/incoming-body": wasmtime_wasi_http::body::HostIncomingBody,
"wasi:http/types/incoming-response": wasmtime_wasi_http::types::HostIncomingResponse,
"wasi:http/types/response-outparam": wasmtime_wasi_http::types::HostResponseOutparam,
"wasi:http/types/outgoing-request": wasmtime_wasi_http::types::HostOutgoingRequest,
"wasi:http/types/incoming-request": wasmtime_wasi_http::types::HostIncomingRequest,
"wasi:http/types/fields": wasmtime_wasi_http::types::HostFields,
"wasi:http/types/request-options": wasmtime_wasi_http::types::HostRequestOptions,
},
});
}
pub fn pre_instanciate_edge_function_component_1_0_0(
engine: &Engine,
component_config: &EdgeFunctionComponents,
) -> anyhow::Result<EdgeFunctionV100Pre<HostState>> {
let mut linker = Linker::new(engine);
wasmtime_wasi::p2::add_to_linker_async(&mut linker)?;
wasmtime_wasi_http::add_only_http_to_linker_async(&mut linker)?;
let span = tracing::info_span!("component-context", component = %component_config.id, category = "edge-function");
let _span = span.enter();
tracing::debug!("Start pre-instantiate edge-function component");
let start = std::time::Instant::now();
let component = crate::helpers::instanciate_component(
engine,
&component_config.file,
&component_config.serialized_file,
)?;
println!(
"Component {} loaded successfully is in {} ms",
component_config.id,
start.elapsed().as_millis()
);
let start = std::time::Instant::now();
let instance_pre = linker.instantiate_pre(&component)?;
println!(
"Component {} instantiated successfully in {} ms",
component_config.id,
start.elapsed().as_millis()
);
let instance_pre = EdgeFunctionV100Pre::new(instance_pre)?;
tracing::debug!("Finished pre-instantiate edge-function component");
Ok(instance_pre)
}
impl ComponentsContext {
pub async fn get_edge_function_1_0_0_instance(
&self,
id: &str,
store: &mut Store<HostState>,
) -> anyhow::Result<EdgeFunctionV100> {
let instance_pre = self.components.edge_function_1_0_0.get(id);
if instance_pre.is_none() {
return Err(anyhow::anyhow!("component not found: {}", id));
}
instance_pre.unwrap().instantiate_async(store).await
}
pub fn add_edge_function_1_0_0_instance(
&mut self,
component_config: EdgeFunctionComponents,
instance_pre: EdgeFunctionV100Pre<HostState>,
) {
if !self
.components
.edge_function_1_0_0
.contains_key(&component_config.id)
{
self.components
.edge_function_1_0_0
.insert(component_config.id.clone(), instance_pre);
}
}
}