Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: introduce ci for tests and clippy #5

Merged
merged 8 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Build and Test

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
CARGO_TERM_COLOR: always

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Build core
run: cargo build -p plugy-core --verbose
- name: Test core
run: cargo test -p plugy-core --verbose
- name: Build macros
run: cargo build -p plugy-macros --verbose
- name: Test macros
run: cargo test -p plugy-macros --verbose
- name: Build runtime
run: cargo build -p plugy-runtime --verbose
- name: Test runtime
run: cargo test -p plugy-runtime --verbose
clippy:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Check the project
run: cargo clippy
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/plugy-core/src/guest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ pub extern "C" fn alloc(len: u32) -> *mut u8 {
#[no_mangle]
pub unsafe extern "C" fn dealloc(value: u64) {
let (ptr, len) = from_bitwise(value);
#[allow(clippy::useless_transmute)]
let ptr = std::mem::transmute::<usize, *mut u8>(ptr as _);
let buffer = Vec::from_raw_parts(ptr, len as _, len as _);
std::mem::drop(buffer);
Expand Down Expand Up @@ -157,6 +158,7 @@ pub fn write_msg<T: serde::ser::Serialize>(value: &T) -> u64 {
/// ```
pub unsafe fn read_msg<T: serde::de::DeserializeOwned>(value: u64) -> T {
let (ptr, len) = from_bitwise(value);
#[allow(clippy::useless_transmute)]
let ptr = std::mem::transmute::<usize, *mut u8>(ptr as _);
let buffer = Vec::from_raw_parts(ptr, len as _, len as _);
bincode::deserialize(&buffer).unwrap()
Expand Down
2 changes: 1 addition & 1 deletion crates/plugy-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ fn generate_async_trait(trait_item: &ItemTrait) -> proc_macro2::TokenStream {
.collect();
quote! {
pub async fn #method_name(#method_inputs) #method_output {
let func = self.handle.get_func(#method_name_str).unwrap();
let func = self.handle.get_func(#method_name_str).await.unwrap();
func.call_unchecked(&(#(#values),*)).await
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/plugy-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dashmap = "5.4.0"
plugy-core = { path = "../plugy-core", version = "0.1.0"}
serde = { version = "1", features = ["derive"] }
wasmtime = "10.0.1"
async-lock = "2.7.0"

[dev-dependencies]
plugy-macros = { path = "../plugy-macros" }
Expand Down
64 changes: 13 additions & 51 deletions crates/plugy-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@ use dashmap::DashMap;
use plugy_core::bitwise::{from_bitwise, into_bitwise};
use serde::{de::DeserializeOwned, Serialize};
use std::fmt;
use std::{
future::Future,
marker::PhantomData,
pin::Pin,
sync::{Arc, Mutex},
};
use std::{future::Future, marker::PhantomData, pin::Pin, sync::Arc};
use wasmtime::{Engine, Instance, Linker, Module, Store};
pub type Caller = Arc<Mutex<Store<Option<RuntimeCaller<()>>>>>;
use async_lock::RwLock;
pub type Caller = Arc<RwLock<Store<Option<RuntimeCaller<()>>>>>;

/// A runtime environment for managing plugins and instances.
///
Expand All @@ -31,7 +27,7 @@ pub type Caller = Arc<Mutex<Store<Option<RuntimeCaller<()>>>>>;
/// }
///
/// fn main() {
/// let runtime = Runtime::<Box dyn Plugin>::new();
/// let runtime = Runtime::<Box<dyn Plugin>>::new();
///
/// // Load and manage plugins...
/// }
Expand All @@ -46,7 +42,7 @@ pub struct Runtime<P> {
#[allow(dead_code)]
pub struct RuntimeModule {
inner: Module,
store: Arc<Mutex<Store<Option<RuntimeCaller<()>>>>>,
store: Caller,
instance: Instance,
}

Expand Down Expand Up @@ -158,7 +154,7 @@ impl<P> Runtime<P> {
name,
RuntimeModule {
inner: module.clone(),
store: Arc::new(Mutex::new(store)),
store: Arc::new(RwLock::new(store)),
instance,
},
);
Expand All @@ -185,7 +181,7 @@ impl<P> Runtime<P> {
let module = self.modules.get(name).unwrap();
Ok(P::into_callable(PluginHandle {
store: module.store.clone(),
instance: module.instance.clone(),
instance: module.instance,
inner: PhantomData::<T>,
}))
}
Expand All @@ -204,7 +200,7 @@ impl<P> Runtime<P> {
#[derive(Debug, Clone)]
pub struct PluginHandle<P> {
instance: Instance,
store: Arc<Mutex<Store<Option<RuntimeCaller<()>>>>>,
store: Caller,
inner: PhantomData<P>,
}

Expand All @@ -230,18 +226,18 @@ impl<P> PluginHandle<P> {
/// Returns a `Result` containing the typed function interface on success,
/// or an `anyhow::Error` if the function retrieval encounters any issues.

pub fn get_func<I: Serialize, R: DeserializeOwned>(
pub async fn get_func<I: Serialize, R: DeserializeOwned>(
&self,
name: &str,
) -> anyhow::Result<Func<I, R>> {
let store = self.store.clone();
let inner_wasm_fn = self.instance.get_typed_func::<u64, u64>(
&mut *store.lock().unwrap(),
&mut *store.write().await,
&format!("_plugy_guest_{name}"),
)?;
Ok(Func {
inner_wasm_fn,
store: store.clone(),
store,
input: std::marker::PhantomData::<I>,
output: std::marker::PhantomData::<R>,
})
Expand All @@ -255,7 +251,7 @@ pub trait IntoCallable<P> {

pub struct Func<P: Serialize, R: DeserializeOwned> {
inner_wasm_fn: wasmtime::TypedFunc<u64, u64>,
store: Arc<Mutex<Store<Option<RuntimeCaller<()>>>>>,
store: Caller,
input: PhantomData<P>,
output: PhantomData<R>,
}
Expand Down Expand Up @@ -293,7 +289,7 @@ impl<P: Serialize, R: DeserializeOwned> Func<P, R> {
/// or an `anyhow::Error` if the function call or deserialization encounters issues.

pub async fn call_checked(&self, value: &P) -> anyhow::Result<R> {
let mut store = self.store.lock().unwrap();
let mut store = self.store.write().await;
let RuntimeCaller {
memory, alloc_fn, ..
} = store.data().clone().unwrap();
Expand All @@ -320,19 +316,6 @@ impl<P: Serialize, R: DeserializeOwned> Func<P, R> {
/// Implementors of this trait provide the ability to asynchronously retrieve
/// the Wasm module data for a plugin.
///
/// # Examples
///
/// ```rust
/// # use plugy::runtime::PluginLoader;
/// #
/// struct MyPluginLoader;
///
/// impl PluginLoader for MyPluginLoader {
/// fn load(&self) -> std::pin::Pin<std::boxed::Box<dyn std::future::Future<Output = Result<Vec<u8>, anyhow::Error>>>> {
/// // ... (implementation details)
/// }
/// }
/// ```
pub trait PluginLoader {
/// Asynchronously loads the Wasm module data for the plugin.
///
Expand All @@ -344,26 +327,5 @@ pub trait PluginLoader {
///
/// Returns a `Pin<Box<dyn Future<Output = Result<Vec<u8>, anyhow::Error>>>>`
/// representing the asynchronous loading process.
///
/// # Examples
///
/// ```rust
/// # use plugy::runtime::PluginLoader;
/// #
/// # struct MyPluginLoader;
/// #
/// # impl PluginLoader for MyPluginLoader {
/// # fn load(&self) -> std::pin::Pin<std::boxed::Box<dyn std::future::Future<Output = Result<Vec<u8>, anyhow::Error>>>> {
/// # Box::pin(async { Ok(Vec::new()) })
/// # }
/// # }
/// #
/// # #[tokio::main]
/// # async fn main() -> anyhow::Result<()> {
/// let loader = MyPluginLoader;
/// let wasm_data: Vec<u8> = loader.load().await?;
/// # Ok(())
/// # }
/// ```
fn load(&self) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, anyhow::Error>>>>;
}