Implement periodic yielding using epoch_deadline_async_yield_and_update
This commit is contained in:
parent
170d27b04c
commit
7f11a32364
3 changed files with 39 additions and 15 deletions
|
@ -23,7 +23,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
async {
|
async {
|
||||||
let mut runtime = PluginBuilder::new_with_default_ctx()
|
let (mut runtime, incrementer) = PluginBuilder::new_with_default_ctx()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.host_function("mystery_number", |input: u32| input + 7)
|
.host_function("mystery_number", |input: u32| input + 7)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -53,6 +53,8 @@ mod tests {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
std::thread::spawn(move || incrementer.block_on());
|
||||||
|
|
||||||
let plugin = TestPlugin {
|
let plugin = TestPlugin {
|
||||||
noop: runtime.function("noop").unwrap(),
|
noop: runtime.function("noop").unwrap(),
|
||||||
constant: runtime.function("constant").unwrap(),
|
constant: runtime.function("constant").unwrap(),
|
||||||
|
|
|
@ -62,6 +62,8 @@ pub struct PluginBuilder {
|
||||||
wasi_ctx: WasiCtx,
|
wasi_ctx: WasiCtx,
|
||||||
engine: Engine,
|
engine: Engine,
|
||||||
linker: Linker<WasiCtxAlloc>,
|
linker: Linker<WasiCtxAlloc>,
|
||||||
|
delta: u64,
|
||||||
|
epoch: std::time::Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a default engine for compiling Wasm.
|
/// Creates a default engine for compiling Wasm.
|
||||||
|
@ -83,10 +85,11 @@ impl PluginBuilder {
|
||||||
let linker = Linker::new(&engine);
|
let linker = Linker::new(&engine);
|
||||||
|
|
||||||
Ok(PluginBuilder {
|
Ok(PluginBuilder {
|
||||||
// host_functions: HashMap::new(),
|
|
||||||
wasi_ctx,
|
wasi_ctx,
|
||||||
engine,
|
engine,
|
||||||
linker,
|
linker,
|
||||||
|
delta: 1,
|
||||||
|
epoch: std::time::Duration::from_millis(100),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +245,17 @@ impl PluginBuilder {
|
||||||
|
|
||||||
/// Initializes a [`Plugin`] from a given compiled Wasm module.
|
/// Initializes a [`Plugin`] from a given compiled Wasm module.
|
||||||
/// Both binary (`.wasm`) and text (`.wat`) module formats are supported.
|
/// Both binary (`.wasm`) and text (`.wat`) module formats are supported.
|
||||||
pub async fn init<T: AsRef<[u8]>>(self, precompiled: bool, module: T) -> Result<Plugin, Error> {
|
pub async fn init<T: AsRef<[u8]>>(
|
||||||
|
self,
|
||||||
|
precompiled: bool,
|
||||||
|
module: T,
|
||||||
|
) -> Result<
|
||||||
|
(
|
||||||
|
Plugin,
|
||||||
|
std::pin::Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
|
||||||
|
),
|
||||||
|
Error,
|
||||||
|
> {
|
||||||
Plugin::init(precompiled, module.as_ref().to_vec(), self).await
|
Plugin::init(precompiled, module.as_ref().to_vec(), self).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,12 +316,17 @@ impl Plugin {
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn init<T, F: Future<Output = ()> + Send + 'static>(
|
async fn init(
|
||||||
precompiled: bool,
|
precompiled: bool,
|
||||||
module: Vec<u8>,
|
module: Vec<u8>,
|
||||||
plugin: PluginBuilder,
|
plugin: PluginBuilder,
|
||||||
spawn_incrementer: impl Fn(F) -> T,
|
) -> Result<
|
||||||
) -> Result<(Self, T), Error> {
|
(
|
||||||
|
Self,
|
||||||
|
std::pin::Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
|
||||||
|
),
|
||||||
|
Error,
|
||||||
|
> {
|
||||||
// initialize the WebAssembly System Interface context
|
// initialize the WebAssembly System Interface context
|
||||||
let engine = plugin.engine;
|
let engine = plugin.engine;
|
||||||
let mut linker = plugin.linker;
|
let mut linker = plugin.linker;
|
||||||
|
@ -323,7 +341,6 @@ impl Plugin {
|
||||||
alloc: None,
|
alloc: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
store.epoch_deadline_async_yield_and_update(1);
|
|
||||||
|
|
||||||
let module = if precompiled {
|
let module = if precompiled {
|
||||||
unsafe { Module::deserialize(&engine, module)? }
|
unsafe { Module::deserialize(&engine, module)? }
|
||||||
|
@ -331,6 +348,16 @@ impl Plugin {
|
||||||
Module::new(&engine, module)?
|
Module::new(&engine, module)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// set up automatic yielding after given duration
|
||||||
|
store.epoch_deadline_async_yield_and_update(plugin.delta);
|
||||||
|
let epoch = plugin.epoch;
|
||||||
|
let incrementer = Box::pin(async move {
|
||||||
|
loop {
|
||||||
|
smol::Timer::after(epoch).await;
|
||||||
|
engine.increment_epoch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// load the provided module into the asynchronous runtime
|
// load the provided module into the asynchronous runtime
|
||||||
linker.module_async(&mut store, "", &module).await?;
|
linker.module_async(&mut store, "", &module).await?;
|
||||||
let instance = linker.instantiate_async(&mut store, &module).await?;
|
let instance = linker.instantiate_async(&mut store, &module).await?;
|
||||||
|
@ -345,13 +372,6 @@ impl Plugin {
|
||||||
});
|
});
|
||||||
|
|
||||||
let plugin = Plugin { store, instance };
|
let plugin = Plugin { store, instance };
|
||||||
let incrementer = spawn_incrementer(async move {
|
|
||||||
loop {
|
|
||||||
smol::Timer::after(std::time::Duration::from_millis(100)).await;
|
|
||||||
|
|
||||||
engine.increment_epoch();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok((plugin, incrementer))
|
Ok((plugin, incrementer))
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::{any::Any, path::PathBuf, sync::Arc};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
pub async fn new_json(executor: Arc<Background>) -> Result<PluginLspAdapter> {
|
pub async fn new_json(executor: Arc<Background>) -> Result<PluginLspAdapter> {
|
||||||
let plugin = PluginBuilder::new_with_default_ctx()?
|
let (plugin, incrementer) = PluginBuilder::new_with_default_ctx()?
|
||||||
.host_function_async("command", |command: String| async move {
|
.host_function_async("command", |command: String| async move {
|
||||||
let mut args = command.split(' ');
|
let mut args = command.split(' ');
|
||||||
let command = args.next().unwrap();
|
let command = args.next().unwrap();
|
||||||
|
@ -25,6 +25,8 @@ pub async fn new_json(executor: Arc<Background>) -> Result<PluginLspAdapter> {
|
||||||
include_bytes!("../../../../plugins/bin/json_language.wasm.pre"),
|
include_bytes!("../../../../plugins/bin/json_language.wasm.pre"),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
executor.spawn(incrementer).detach();
|
||||||
PluginLspAdapter::new(plugin, executor).await
|
PluginLspAdapter::new(plugin, executor).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue