module loading works
This commit is contained in:
11
Cargo.lock
generated
11
Cargo.lock
generated
@@ -1116,6 +1116,16 @@ version = "0.2.155"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libloading"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"windows-targets 0.52.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.14"
|
version = "0.4.14"
|
||||||
@@ -1268,6 +1278,7 @@ dependencies = [
|
|||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
"home",
|
"home",
|
||||||
"interner",
|
"interner",
|
||||||
|
"libloading",
|
||||||
"nix",
|
"nix",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ path = "src/platform/os/main.rs"
|
|||||||
required-features = [ "os-target" ]
|
required-features = [ "os-target" ]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
os-target = [ "clap", "home", "daemonize", "nix", "toml", "sysinfo", "ciborium/default", "tracing-subscriber", "async", "tracing-subscriber/env-filter"]
|
os-target = [ "clap", "home", "daemonize", "nix", "toml", "sysinfo", "ciborium/default", "tracing-subscriber", "async", "tracing-subscriber/env-filter", "libloading" ]
|
||||||
wasm-target = [ "wasm-bindgen", "console_error_panic_hook", "wasm-bindgen-cli" ]
|
wasm-target = [ "wasm-bindgen", "console_error_panic_hook", "wasm-bindgen-cli" ]
|
||||||
async = ["tokio/net", "tokio", "tokio/rt-multi-thread", "tokio/io-util"]
|
async = ["tokio/net", "tokio", "tokio/rt-multi-thread", "tokio/io-util"]
|
||||||
|
|
||||||
@@ -33,6 +33,9 @@ tracing = "0.1.40"
|
|||||||
serde_json = { version = "1.0.117", optional = false }
|
serde_json = { version = "1.0.117", optional = false }
|
||||||
crossbeam = "0.8.4"
|
crossbeam = "0.8.4"
|
||||||
|
|
||||||
|
# buildin modules
|
||||||
|
#mize_module_blob = { path = "./modules/modules/Blob" }
|
||||||
|
|
||||||
# wasm dependencies
|
# wasm dependencies
|
||||||
wasm-bindgen = { version = "0.2.84", optional = true }
|
wasm-bindgen = { version = "0.2.84", optional = true }
|
||||||
console_error_panic_hook = { version = "0.1.7", optional = true }
|
console_error_panic_hook = { version = "0.1.7", optional = true }
|
||||||
@@ -47,6 +50,7 @@ toml = { version = "0.8.13", features = ["parse"], optional = true }
|
|||||||
sysinfo = { version = "0.30.12", optional = true }
|
sysinfo = { version = "0.30.12", optional = true }
|
||||||
tracing-subscriber = { version = "0.3.18", optional = true }
|
tracing-subscriber = { version = "0.3.18", optional = true }
|
||||||
tokio = { version = "1.21.0", features = ["sync"], optional = true }
|
tokio = { version = "1.21.0", features = ["sync"], optional = true }
|
||||||
|
libloading = { version = "0.8.5", optional = true }
|
||||||
|
|
||||||
# bare dependencies
|
# bare dependencies
|
||||||
|
|
||||||
|
|||||||
26
build.rs
Normal file
26
build.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use std::process::Command;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
// compile the string plugin
|
||||||
|
//let _out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
//let mut string_module = Command::new("bash");
|
||||||
|
//string_module.arg("-c");
|
||||||
|
//string_module.arg("echo hiiiiiiiiiiiiiiiii");
|
||||||
|
//string_module.arg("--help");
|
||||||
|
//string_module.arg("--out-dir");
|
||||||
|
//string_module.arg(out_dir);
|
||||||
|
//string_module.env("PWD", "/hoem/me/work/mize/module/modules/Blob");
|
||||||
|
|
||||||
|
//let _res = string_module.spawn();
|
||||||
|
//let _child = Command::new("cargo")
|
||||||
|
//.arg("build")
|
||||||
|
//.arg("--lib")
|
||||||
|
//.arg("--manifest-path")
|
||||||
|
//.arg("/home/me/work/mize/modules/modules/Blob/Cargo.toml")
|
||||||
|
//.spawn()
|
||||||
|
//.expect("failed to start wasm build");
|
||||||
|
|
||||||
|
//to outdir (), using the nightly feature --out-dir to have the result there. By default I get a libhearts.rlib
|
||||||
|
}
|
||||||
2
modules
2
modules
Submodule modules updated: b670350309...a605c0efb1
@@ -20,7 +20,7 @@ use crate::instance::subscription::Subscription;
|
|||||||
use crate::item::{Item, ItemData};
|
use crate::item::{Item, ItemData};
|
||||||
use crate::memstore::MemStore;
|
use crate::memstore::MemStore;
|
||||||
use crate::instance::updater::Operation;
|
use crate::instance::updater::Operation;
|
||||||
use crate::mize_err;
|
use crate::{mize_err, Module};
|
||||||
use crate::proto::MizeMessage;
|
use crate::proto::MizeMessage;
|
||||||
|
|
||||||
use self::connection::{ConnListener, Connection};
|
use self::connection::{ConnListener, Connection};
|
||||||
@@ -51,6 +51,7 @@ pub struct Instance {
|
|||||||
connections: Arc<Mutex<Vec<Connection>>>,
|
connections: Arc<Mutex<Vec<Connection>>>,
|
||||||
next_con_id: Arc<Mutex<u64>>,
|
next_con_id: Arc<Mutex<u64>>,
|
||||||
subs: Arc<Mutex<HashMap<MizeId, Vec<Subscription>>>>,
|
subs: Arc<Mutex<HashMap<MizeId, Vec<Subscription>>>>,
|
||||||
|
pub modules: Arc<Mutex<HashMap<String, Box<dyn Module + Sync + Send>>>>,
|
||||||
pub id_pool: Arc<Mutex<VecStringPool>>,
|
pub id_pool: Arc<Mutex<VecStringPool>>,
|
||||||
pub namespace_pool: Arc<Mutex<StringPool>>,
|
pub namespace_pool: Arc<Mutex<StringPool>>,
|
||||||
|
|
||||||
@@ -96,6 +97,7 @@ impl Instance {
|
|||||||
connections, subs, id_pool,
|
connections, subs, id_pool,
|
||||||
namespace, self_namespace, op_tx,
|
namespace, self_namespace, op_tx,
|
||||||
namespace_pool: Arc::new(Mutex::new(namespace_pool_raw)),
|
namespace_pool: Arc::new(Mutex::new(namespace_pool_raw)),
|
||||||
|
modules: Arc::new(Mutex::new(HashMap::new())),
|
||||||
context: vec![],
|
context: vec![],
|
||||||
threads: vec![],
|
threads: vec![],
|
||||||
next_con_id: Arc::new(Mutex::new(1)),
|
next_con_id: Arc::new(Mutex::new(1)),
|
||||||
@@ -115,7 +117,8 @@ impl Instance {
|
|||||||
let closure_two = move || updater_thread(op_rx, &instance_clone_two);
|
let closure_two = move || updater_thread(op_rx, &instance_clone_two);
|
||||||
instance.spawn("updater_thread", closure_two)?;
|
instance.spawn("updater_thread", closure_two)?;
|
||||||
|
|
||||||
// will probably move the msg stuff into it's own thread
|
// will move the msg stuff into it's own thread
|
||||||
|
// like this it can deadlock.... if a msg waits on an operation to complete
|
||||||
//let msg_instance_clone = instance.clone();
|
//let msg_instance_clone = instance.clone();
|
||||||
//let msg_closure = move || msg_thread(op_rx, instance_clone);
|
//let msg_closure = move || msg_thread(op_rx, instance_clone);
|
||||||
//instance.spawn("msg_thread", closure)?;
|
//instance.spawn("msg_thread", closure)?;
|
||||||
@@ -142,6 +145,16 @@ impl Instance {
|
|||||||
crate::platform::any::instance_init(self);
|
crate::platform::any::instance_init(self);
|
||||||
|
|
||||||
// end of platform specific init code
|
// end of platform specific init code
|
||||||
|
self.load_module("Blob")?;
|
||||||
|
|
||||||
|
let mut modules_inner = self.modules.lock()?;
|
||||||
|
|
||||||
|
let module = modules_inner.get_mut("Blob").unwrap();
|
||||||
|
|
||||||
|
println!("right before segfault");
|
||||||
|
module.init(&self);
|
||||||
|
|
||||||
|
//self.load_module("String")?;
|
||||||
|
|
||||||
debug!("INSTANCE INIT DONE");
|
debug!("INSTANCE INIT DONE");
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -275,6 +288,11 @@ impl Instance {
|
|||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_module(&mut self, name: &str) -> MizeResult<()> {
|
||||||
|
// platform specific init code
|
||||||
|
crate::platform::any::load_module(self, name)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn namespace_from_string(&self, ns_str: String) -> MizeResult<Namespace> {
|
pub fn namespace_from_string(&self, ns_str: String) -> MizeResult<Namespace> {
|
||||||
let namespace_pool_inner = self.namespace_pool.lock()?;
|
let namespace_pool_inner = self.namespace_pool.lock()?;
|
||||||
let namespace = Namespace ( namespace_pool_inner.get(ns_str) );
|
let namespace = Namespace ( namespace_pool_inner.get(ns_str) );
|
||||||
|
|||||||
@@ -2,5 +2,28 @@
|
|||||||
|
|
||||||
// https://users.rust-lang.org/t/casting-between-trait-object-types/97220/2
|
// https://users.rust-lang.org/t/casting-between-trait-object-types/97220/2
|
||||||
|
|
||||||
|
use crate::instance::Instance;
|
||||||
|
use crate::error::MizeResult;
|
||||||
|
|
||||||
pub trait Module {
|
pub trait Module {
|
||||||
|
fn init(&mut self, instance: &Instance) -> MizeResult<()>;
|
||||||
|
|
||||||
|
fn exit(&mut self, instance: &Instance) -> MizeResult<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct EmptyModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Module for EmptyModule {
|
||||||
|
fn init(&mut self, instance: &Instance) -> MizeResult<()> {
|
||||||
|
println!("empty module fn init");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn exit(&mut self, instance: &Instance) -> MizeResult<()> {
|
||||||
|
println!("empty module fn exit");
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
21
src/lib.rs
21
src/lib.rs
@@ -15,7 +15,10 @@ mod core {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub use core::*;
|
pub use core::*;
|
||||||
|
pub use core::instance::module::Module;
|
||||||
|
pub use core::instance::Instance;
|
||||||
|
pub use core::error::MizeError;
|
||||||
|
pub use core::error::MizeResult;
|
||||||
|
|
||||||
// platform specific stuff
|
// platform specific stuff
|
||||||
pub mod platform {
|
pub mod platform {
|
||||||
@@ -31,8 +34,24 @@ pub mod platform {
|
|||||||
|
|
||||||
#[cfg(feature = "os-target")]
|
#[cfg(feature = "os-target")]
|
||||||
pub use super::os::os_instance_init as instance_init;
|
pub use super::os::os_instance_init as instance_init;
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "os-target", feature = "wasm-target")))]
|
||||||
|
pub use super::super::instance_init;
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(feature = "os-target")]
|
||||||
|
pub use super::os::load_module;
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "os-target", feature = "wasm-target")))]
|
||||||
|
pub use super::super::load_module;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn instance_init(instance: &mut core::instance::Instance) {}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn load_module(instance: &mut core::instance::Instance, name: &str) -> MizeResult<()> { Ok(()) }
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use std::fs;
|
|||||||
use tracing::{debug, error, info, trace, warn};
|
use tracing::{debug, error, info, trace, warn};
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::time::UNIX_EPOCH;
|
||||||
|
|
||||||
use crate::id::MizeId;
|
use crate::id::MizeId;
|
||||||
use crate::instance::store::Store;
|
use crate::instance::store::Store;
|
||||||
@@ -12,8 +13,9 @@ use crate::instance::Instance;
|
|||||||
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
||||||
use crate::item::{ItemData, IntoItemData};
|
use crate::item::{ItemData, IntoItemData};
|
||||||
use crate::memstore::MemStore;
|
use crate::memstore::MemStore;
|
||||||
use crate::mize_err;
|
use crate::{mize_err, Module};
|
||||||
use crate::platform::os::unix_socket::UnixListener;
|
use crate::platform::os::unix_socket::UnixListener;
|
||||||
|
use crate::instance::module::EmptyModule;
|
||||||
|
|
||||||
use self::fsstore::FileStore;
|
use self::fsstore::FileStore;
|
||||||
|
|
||||||
@@ -63,17 +65,17 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> {
|
|||||||
|
|
||||||
////// if a config.store_path is set, upgrade to the filestore there
|
////// if a config.store_path is set, upgrade to the filestore there
|
||||||
let mut test = instance.get("0")?.as_data_full()?;
|
let mut test = instance.get("0")?.as_data_full()?;
|
||||||
let mut store_path = instance.get("0/config/store_path")?.value_string()?;
|
let mut store_path = match instance.get("0/config/store_path")?.value_string() {
|
||||||
|
Ok(path) => path,
|
||||||
if store_path == "" {
|
Err(e) => {
|
||||||
|
// the default store_path: $HOME/.mize
|
||||||
let home_dir = env!("HOME");
|
let home_dir = env!("HOME");
|
||||||
if home_dir == "" {
|
if home_dir == "" {
|
||||||
return Err(mize_err!("env var $HOME empty"));
|
return Err(mize_err!("env var $HOME empty"));
|
||||||
}
|
}
|
||||||
|
home_dir.to_owned() + "/.mize"
|
||||||
// the default store_path: $HOME/.mize
|
},
|
||||||
store_path = home_dir.to_owned() + "/.mize";
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if FileStore::store_is_opened(store_path.to_owned())? {
|
if FileStore::store_is_opened(store_path.to_owned())? {
|
||||||
// if the store is already opened, connect to the instance, that opened it and join
|
// if the store is already opened, connect to the instance, that opened it and join
|
||||||
@@ -94,6 +96,62 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn seconds_since_modification(path: &Path) -> u64 {
|
||||||
|
let metadata = match fs::metadata(path) {
|
||||||
|
Err(_) => { return u64::MAX; }, // we are the older file, if it fails
|
||||||
|
Ok(data) => data,
|
||||||
|
};
|
||||||
|
|
||||||
|
let modified = match metadata.modified() {
|
||||||
|
Err(_) => { return u64::MAX; }, // we are the older file, if it fails
|
||||||
|
Ok(data) => data,
|
||||||
|
};
|
||||||
|
|
||||||
|
let duration = match modified.duration_since(UNIX_EPOCH) {
|
||||||
|
Err(_) => { return u64::MAX; }, // we are the older file, if it fails
|
||||||
|
Ok(data) => data,
|
||||||
|
};
|
||||||
|
|
||||||
|
duration.as_secs()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_module(instance: &mut Instance, name: &str) -> MizeResult<()> {
|
||||||
|
|
||||||
|
let module_dir_str = instance.get("0/config/module_dir")?.value_string()?;
|
||||||
|
let module_dir = Path::new(&module_dir_str);
|
||||||
|
|
||||||
|
let release_path = module_dir.join("modules").join(name).join("target").join("release").join(format!("libmize_module_{}.so", name));
|
||||||
|
let debug_path = module_dir.join("modules").join(name).join("target").join("debug").join(format!("libmize_module_{}.so", name));
|
||||||
|
|
||||||
|
let module_path = match seconds_since_modification(&release_path) > seconds_since_modification(&debug_path) {
|
||||||
|
true => debug_path,
|
||||||
|
false => release_path,
|
||||||
|
};
|
||||||
|
|
||||||
|
let lib = unsafe { libloading::Library::new(module_path)? };
|
||||||
|
|
||||||
|
let func: libloading::Symbol<unsafe extern "C" fn(&mut Box<dyn Module + Send + Sync>) -> ()> = unsafe { lib.get(format!("get_mize_module_{}", name).as_bytes())? };
|
||||||
|
|
||||||
|
let mut module: Box<dyn Module + Send + Sync> = Box::new(EmptyModule {});
|
||||||
|
|
||||||
|
unsafe { func(&mut module) };
|
||||||
|
|
||||||
|
|
||||||
|
let mut modules_inner = instance.modules.lock()?;
|
||||||
|
|
||||||
|
module.init(&instance);
|
||||||
|
|
||||||
|
modules_inner.insert(name.to_owned(), module);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// dropping the lib, would (i suspect) free all memory, of the library's code, which would
|
||||||
|
// make the module's vtable point into empty memory
|
||||||
|
std::mem::forget(lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn config_from_cli_args(matches: &ArgMatches) -> MizeResult<ItemData> {
|
pub fn config_from_cli_args(matches: &ArgMatches) -> MizeResult<ItemData> {
|
||||||
|
|
||||||
let mut config = ItemData::new();
|
let mut config = ItemData::new();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
[config]
|
[config]
|
||||||
namespace = "test.c2vi.dev"
|
namespace = "test.c2vi.dev"
|
||||||
|
module_dir = "/home/me/work/mize/modules"
|
||||||
test = "hello from test item"
|
test = "hello from test item"
|
||||||
store_path = "/home/me/.mize"
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "instance",
|
|
||||||
"paths": [
|
|
||||||
[["daemon", "pid"], "int"],
|
|
||||||
[["daemon", "log", "blob"]]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user