mirror of
https://github.com/fluencelabs/marine.git
synced 2024-12-12 14:55:32 +00:00
Get file name of the interpreter from a config (#48)
This commit is contained in:
parent
d12a6c152a
commit
2dc09858a8
@ -28,8 +28,8 @@ use fluence_faas::IValue;
|
|||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use crate::errors::AquamarineVMError::InvalidAquamarinePath;
|
||||||
|
|
||||||
const AQUAMARINE_WASM_FILE_NAME: &str = "aquamarine";
|
|
||||||
const CALL_SERVICE_NAME: &str = "call_service";
|
const CALL_SERVICE_NAME: &str = "call_service";
|
||||||
const CURRENT_PEER_ID_ENV_NAME: &str = "CURRENT_PEER_ID";
|
const CURRENT_PEER_ID_ENV_NAME: &str = "CURRENT_PEER_ID";
|
||||||
|
|
||||||
@ -38,6 +38,8 @@ unsafe impl Send for AquamarineVM {}
|
|||||||
pub struct AquamarineVM {
|
pub struct AquamarineVM {
|
||||||
faas: FluenceFaaS,
|
faas: FluenceFaaS,
|
||||||
particle_data_store: PathBuf,
|
particle_data_store: PathBuf,
|
||||||
|
/// file name of the AIR interpreter .wasm
|
||||||
|
wasm_filename: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AquamarineVM {
|
impl AquamarineVM {
|
||||||
@ -45,8 +47,11 @@ impl AquamarineVM {
|
|||||||
pub fn new(config: AquamarineVMConfig) -> Result<Self> {
|
pub fn new(config: AquamarineVMConfig) -> Result<Self> {
|
||||||
use AquamarineVMError::InvalidDataStorePath;
|
use AquamarineVMError::InvalidDataStorePath;
|
||||||
|
|
||||||
let faas_config = Self::make_faas_config(
|
let (wasm_dir, wasm_filename) = split_dirname(config.aquamarine_wasm_path)?;
|
||||||
config.aquamarine_wasm_path,
|
|
||||||
|
let faas_config = make_faas_config(
|
||||||
|
wasm_dir,
|
||||||
|
&wasm_filename,
|
||||||
config.call_service,
|
config.call_service,
|
||||||
config.current_peer_id,
|
config.current_peer_id,
|
||||||
config.logging_mask,
|
config.logging_mask,
|
||||||
@ -60,6 +65,7 @@ impl AquamarineVM {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
faas,
|
faas,
|
||||||
particle_data_store,
|
particle_data_store,
|
||||||
|
wasm_filename,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,131 +88,153 @@ impl AquamarineVM {
|
|||||||
IValue::String(data.into()),
|
IValue::String(data.into()),
|
||||||
];
|
];
|
||||||
|
|
||||||
let result = self.faas.call_with_ivalues(
|
let result =
|
||||||
AQUAMARINE_WASM_FILE_NAME,
|
self.faas
|
||||||
"invoke",
|
.call_with_ivalues(&self.wasm_filename, "invoke", &args, <_>::default())?;
|
||||||
&args,
|
|
||||||
<_>::default(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let raw_outcome = Self::make_raw_outcome(result)?;
|
let raw_outcome = make_raw_outcome(result)?;
|
||||||
std::fs::write(&prev_data_path, &raw_outcome.data)
|
std::fs::write(&prev_data_path, &raw_outcome.data)
|
||||||
.map_err(|e| PersistDataError(e, prev_data_path))?;
|
.map_err(|e| PersistDataError(e, prev_data_path))?;
|
||||||
|
|
||||||
raw_outcome.try_into()
|
raw_outcome.try_into()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn make_faas_config(
|
/// Splits given path into its directory and file stem
|
||||||
aquamarine_wasm_path: PathBuf,
|
///
|
||||||
call_service: HostImportDescriptor,
|
/// # Example
|
||||||
current_peer_id: String,
|
/// For path `/path/to/aquamarine.wasm` result will be `Ok(PathBuf(/path/to), "aquamarine")`
|
||||||
logging_mask: i64,
|
fn split_dirname(path: PathBuf) -> Result<(PathBuf, String)> {
|
||||||
) -> FaaSConfig {
|
let metadata = path.metadata().map_err(|err| InvalidAquamarinePath {
|
||||||
use maplit::hashmap;
|
invalid_path: path.clone(),
|
||||||
|
reason: "failed to get file's metadata (doesn't exist or invalid permissions)",
|
||||||
|
io_error: Some(err),
|
||||||
|
})?;
|
||||||
|
|
||||||
let make_faas_module_config = |call_service: HostImportDescriptor| {
|
if !metadata.is_file() {
|
||||||
use fluence_faas::FaaSModuleConfig;
|
return Err(InvalidAquamarinePath {
|
||||||
|
invalid_path: path,
|
||||||
let host_imports = hashmap! {
|
reason: "is not a file",
|
||||||
String::from(CALL_SERVICE_NAME) => call_service
|
io_error: None,
|
||||||
};
|
});
|
||||||
|
|
||||||
FaaSModuleConfig {
|
|
||||||
mem_pages_count: None,
|
|
||||||
logger_enabled: true,
|
|
||||||
host_imports,
|
|
||||||
wasi: None,
|
|
||||||
logging_mask,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut aquamarine_module_config = make_faas_module_config(call_service);
|
|
||||||
|
|
||||||
let envs = hashmap! {
|
|
||||||
CURRENT_PEER_ID_ENV_NAME.as_bytes().to_vec() => current_peer_id.into_bytes(),
|
|
||||||
};
|
|
||||||
aquamarine_module_config.extend_wasi_envs(envs);
|
|
||||||
|
|
||||||
let mut aquamarine_wasm_dir = aquamarine_wasm_path;
|
|
||||||
// faas config requires a path to the directory with Wasm modules
|
|
||||||
aquamarine_wasm_dir.pop();
|
|
||||||
|
|
||||||
FaaSConfig {
|
|
||||||
modules_dir: Some(aquamarine_wasm_dir),
|
|
||||||
modules_config: vec![(
|
|
||||||
String::from(AQUAMARINE_WASM_FILE_NAME),
|
|
||||||
aquamarine_module_config,
|
|
||||||
)],
|
|
||||||
default_modules_config: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_raw_outcome(mut result: Vec<IValue>) -> Result<RawStepperOutcome> {
|
let file_stem = path
|
||||||
use AquamarineVMError::AquamarineResultError as ResultError;
|
.file_stem()
|
||||||
|
.expect("checked to be a file, file name must be defined");
|
||||||
|
let file_stem = file_stem.to_string_lossy().into_owned();
|
||||||
|
|
||||||
match result.remove(0) {
|
let mut path = path;
|
||||||
IValue::Record(record_values) => {
|
// drop file name from path
|
||||||
let mut record_values = record_values.into_vec();
|
path.pop();
|
||||||
if record_values.len() != 3 {
|
|
||||||
return Err(ResultError(format!(
|
|
||||||
"expected StepperOutcome struct with 3 fields, got {:?}",
|
|
||||||
record_values
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
let ret_code = match record_values.remove(0) {
|
Ok((path, file_stem))
|
||||||
IValue::S32(ret_code) => ret_code,
|
}
|
||||||
v => {
|
|
||||||
return Err(ResultError(format!(
|
|
||||||
"expected i32 for ret_code, got {:?}",
|
|
||||||
v
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let data = match record_values.remove(0) {
|
fn make_faas_config(
|
||||||
IValue::String(str) => str,
|
aquamarine_wasm_dir: PathBuf,
|
||||||
v => {
|
aquamarine_wasm_file: &str,
|
||||||
return Err(ResultError(format!(
|
call_service: HostImportDescriptor,
|
||||||
"expected string for data, got {:?}",
|
current_peer_id: String,
|
||||||
v
|
logging_mask: i64,
|
||||||
)))
|
) -> FaaSConfig {
|
||||||
}
|
use maplit::hashmap;
|
||||||
};
|
|
||||||
|
|
||||||
let next_peer_pks = match record_values.remove(0) {
|
let make_faas_module_config = |call_service: HostImportDescriptor| {
|
||||||
IValue::Array(ar_values) => {
|
use fluence_faas::FaaSModuleConfig;
|
||||||
let array = ar_values
|
|
||||||
.into_iter()
|
|
||||||
.map(|v| match v {
|
|
||||||
IValue::String(str) => Ok(str),
|
|
||||||
v => Err(ResultError(format!(
|
|
||||||
"expected string for next_peer_pks, got {:?}",
|
|
||||||
v
|
|
||||||
))),
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<String>>>()?;
|
|
||||||
|
|
||||||
Ok(array)
|
let host_imports = hashmap! {
|
||||||
}
|
String::from(CALL_SERVICE_NAME) => call_service
|
||||||
v => Err(ResultError(format!(
|
};
|
||||||
"expected array for next_peer_pks, got {:?}",
|
|
||||||
v
|
|
||||||
))),
|
|
||||||
}?;
|
|
||||||
|
|
||||||
Ok(RawStepperOutcome {
|
FaaSModuleConfig {
|
||||||
ret_code,
|
mem_pages_count: None,
|
||||||
data,
|
logger_enabled: true,
|
||||||
next_peer_pks,
|
host_imports,
|
||||||
})
|
wasi: None,
|
||||||
}
|
logging_mask,
|
||||||
v => {
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut aquamarine_module_config = make_faas_module_config(call_service);
|
||||||
|
|
||||||
|
let envs = hashmap! {
|
||||||
|
CURRENT_PEER_ID_ENV_NAME.as_bytes().to_vec() => current_peer_id.into_bytes(),
|
||||||
|
};
|
||||||
|
aquamarine_module_config.extend_wasi_envs(envs);
|
||||||
|
|
||||||
|
FaaSConfig {
|
||||||
|
modules_dir: Some(aquamarine_wasm_dir),
|
||||||
|
modules_config: vec![(String::from(aquamarine_wasm_file), aquamarine_module_config)],
|
||||||
|
default_modules_config: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_raw_outcome(mut result: Vec<IValue>) -> Result<RawStepperOutcome> {
|
||||||
|
use AquamarineVMError::AquamarineResultError as ResultError;
|
||||||
|
|
||||||
|
match result.remove(0) {
|
||||||
|
IValue::Record(record_values) => {
|
||||||
|
let mut record_values = record_values.into_vec();
|
||||||
|
if record_values.len() != 3 {
|
||||||
return Err(ResultError(format!(
|
return Err(ResultError(format!(
|
||||||
"expected record for StepperOutcome, got {:?}",
|
"expected StepperOutcome struct with 3 fields, got {:?}",
|
||||||
v
|
record_values
|
||||||
)))
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let ret_code = match record_values.remove(0) {
|
||||||
|
IValue::S32(ret_code) => ret_code,
|
||||||
|
v => {
|
||||||
|
return Err(ResultError(format!(
|
||||||
|
"expected i32 for ret_code, got {:?}",
|
||||||
|
v
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let data = match record_values.remove(0) {
|
||||||
|
IValue::String(str) => str,
|
||||||
|
v => {
|
||||||
|
return Err(ResultError(format!(
|
||||||
|
"expected string for data, got {:?}",
|
||||||
|
v
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let next_peer_pks = match record_values.remove(0) {
|
||||||
|
IValue::Array(ar_values) => {
|
||||||
|
let array = ar_values
|
||||||
|
.into_iter()
|
||||||
|
.map(|v| match v {
|
||||||
|
IValue::String(str) => Ok(str),
|
||||||
|
v => Err(ResultError(format!(
|
||||||
|
"expected string for next_peer_pks, got {:?}",
|
||||||
|
v
|
||||||
|
))),
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<String>>>()?;
|
||||||
|
|
||||||
|
Ok(array)
|
||||||
|
}
|
||||||
|
v => Err(ResultError(format!(
|
||||||
|
"expected array for next_peer_pks, got {:?}",
|
||||||
|
v
|
||||||
|
))),
|
||||||
|
}?;
|
||||||
|
|
||||||
|
Ok(RawStepperOutcome {
|
||||||
|
ret_code,
|
||||||
|
data,
|
||||||
|
next_peer_pks,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
v => {
|
||||||
|
return Err(ResultError(format!(
|
||||||
|
"expected record for StepperOutcome, got {:?}",
|
||||||
|
v
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,14 +256,11 @@ impl AquamarineVM {
|
|||||||
IValue::String(data.into()),
|
IValue::String(data.into()),
|
||||||
];
|
];
|
||||||
|
|
||||||
let result = self.faas.call_with_ivalues(
|
let result =
|
||||||
AQUAMARINE_WASM_FILE_NAME,
|
self.faas
|
||||||
"invoke",
|
.call_with_ivalues(&self.wasm_filename, "invoke", &args, <_>::default())?;
|
||||||
&args,
|
|
||||||
<_>::default(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let raw_outcome = Self::make_raw_outcome(result)?;
|
let raw_outcome = make_raw_outcome(result)?;
|
||||||
raw_outcome.try_into()
|
raw_outcome.try_into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,13 @@ pub enum AquamarineVMError {
|
|||||||
|
|
||||||
/// Errors related to particle_data_store path from supplied config.
|
/// Errors related to particle_data_store path from supplied config.
|
||||||
InvalidDataStorePath(IOError, PathBuf),
|
InvalidDataStorePath(IOError, PathBuf),
|
||||||
|
|
||||||
|
/// Specified path to AIR interpreter .wasm file was invalid
|
||||||
|
InvalidAquamarinePath {
|
||||||
|
invalid_path: PathBuf,
|
||||||
|
io_error: Option<IOError>,
|
||||||
|
reason: &'static str,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for AquamarineVMError {}
|
impl Error for AquamarineVMError {}
|
||||||
@ -57,6 +64,18 @@ impl std::fmt::Display for AquamarineVMError {
|
|||||||
"an error occurred while creating data storage {:?} by {:?} path",
|
"an error occurred while creating data storage {:?} by {:?} path",
|
||||||
err, path
|
err, path
|
||||||
),
|
),
|
||||||
|
|
||||||
|
AquamarineVMError::InvalidAquamarinePath {
|
||||||
|
invalid_path,
|
||||||
|
io_error,
|
||||||
|
reason,
|
||||||
|
} => {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"path to AIR interpreter .wasm ({:?}) is invalid: {}; IO Error: {:?}",
|
||||||
|
invalid_path, reason, io_error
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user