@@ -604,15 +604,28 @@ impl WasmHost {
let this = self.clone();
let manifest = manifest.clone();
let executor = cx.background_executor().clone();
- let load_extension_task = async move {
- let zed_api_version = parse_wasm_extension_version(&manifest.id, &wasm_bytes)?;
- let component = Component::from_binary(&this.engine, &wasm_bytes)
- .context("failed to compile wasm component")?;
+ // Parse version and compile component on gpui's background executor.
+ // These are cpu-bound operations that don't require a tokio runtime.
+ let compile_task = {
+ let manifest_id = manifest.id.clone();
+ let engine = this.engine.clone();
+
+ executor.spawn(async move {
+ let zed_api_version = parse_wasm_extension_version(&manifest_id, &wasm_bytes)?;
+ let component = Component::from_binary(&engine, &wasm_bytes)
+ .context("failed to compile wasm component")?;
+
+ anyhow::Ok((zed_api_version, component))
+ })
+ };
+
+ let load_extension = |zed_api_version: Version, component| async move {
+ let wasi_ctx = this.build_wasi_ctx(&manifest).await?;
let mut store = wasmtime::Store::new(
&this.engine,
WasmState {
- ctx: this.build_wasi_ctx(&manifest).await?,
+ ctx: wasi_ctx,
manifest: manifest.clone(),
table: ResourceTable::new(),
host: this.clone(),
@@ -661,11 +674,17 @@ impl WasmHost {
zed_api_version,
))
};
+
cx.spawn(async move |cx| {
+ let (zed_api_version, component) = compile_task.await?;
+
+ // Run wasi-dependent operations on tokio.
+ // wasmtime_wasi internally uses tokio for I/O operations.
let (extension_task, manifest, work_dir, tx, zed_api_version) =
- cx.background_executor().spawn(load_extension_task).await?;
- // we need to run run the task in a tokio context as wasmtime_wasi may
- // call into tokio, accessing its runtime handle when we trigger the `engine.increment_epoch()` above.
+ gpui_tokio::Tokio::spawn(cx, load_extension(zed_api_version, component))?.await??;
+
+ // Run the extension message loop on tokio since extension
+ // calls may invoke wasi functions that require a tokio runtime.
let task = Arc::new(gpui_tokio::Tokio::spawn(cx, extension_task)?);
Ok(WasmExtension {