Add with_module_names constructor to FluenceFaaS (#11)

This commit is contained in:
folex 2020-07-20 17:13:11 +03:00 committed by GitHub
parent ee55c63ff8
commit fa3ae391ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 114 additions and 30 deletions

36
Cargo.lock generated
View File

@ -343,9 +343,9 @@ dependencies = [
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.2.5" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b480f641ccf0faf324e20c1d3e53d81b7484c698b42ea677f6907ae4db195371" checksum = "6eab5ee3df98a279d9b316b1af6ac95422127b1290317e6d18c1743c99418b01"
dependencies = [ dependencies = [
"errno-dragonfly", "errno-dragonfly",
"libc", "libc",
@ -434,7 +434,7 @@ dependencies = [
[[package]] [[package]]
name = "fluence" name = "fluence"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/fluencelabs/rust-sdk#be47b96ce8e067296c37680c4083130c2ce9c859" source = "git+https://github.com/fluencelabs/rust-sdk#79a5896015659ddb1c20526c4aa142b8afae35ad"
dependencies = [ dependencies = [
"fluence-sdk-macro", "fluence-sdk-macro",
"fluence-sdk-main", "fluence-sdk-main",
@ -459,7 +459,7 @@ dependencies = [
[[package]] [[package]]
name = "fluence-sdk-macro" name = "fluence-sdk-macro"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/fluencelabs/rust-sdk#be47b96ce8e067296c37680c4083130c2ce9c859" source = "git+https://github.com/fluencelabs/rust-sdk#79a5896015659ddb1c20526c4aa142b8afae35ad"
dependencies = [ dependencies = [
"fluence-sdk-wit", "fluence-sdk-wit",
] ]
@ -467,7 +467,7 @@ dependencies = [
[[package]] [[package]]
name = "fluence-sdk-main" name = "fluence-sdk-main"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/fluencelabs/rust-sdk#be47b96ce8e067296c37680c4083130c2ce9c859" source = "git+https://github.com/fluencelabs/rust-sdk#79a5896015659ddb1c20526c4aa142b8afae35ad"
dependencies = [ dependencies = [
"log", "log",
] ]
@ -475,7 +475,7 @@ dependencies = [
[[package]] [[package]]
name = "fluence-sdk-wit" name = "fluence-sdk-wit"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/fluencelabs/rust-sdk#be47b96ce8e067296c37680c4083130c2ce9c859" source = "git+https://github.com/fluencelabs/rust-sdk#79a5896015659ddb1c20526c4aa142b8afae35ad"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -566,6 +566,15 @@ dependencies = [
"fluence-faas", "fluence-faas",
] ]
[[package]]
name = "hashbrown"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.3.1" version = "0.3.1"
@ -607,11 +616,12 @@ checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.4.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe" checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown",
"serde", "serde",
] ]
@ -680,9 +690,9 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.72" version = "0.2.73"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701" checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
@ -845,9 +855,9 @@ checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.18" version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
@ -1374,7 +1384,7 @@ dependencies = [
[[package]] [[package]]
name = "wasmer-interface-types" name = "wasmer-interface-types"
version = "0.17.0" version = "0.17.0"
source = "git+https://github.com/fluencelabs/interface-types?branch=byte_array#bb9e4dbdfc0da6e6803392664a1c34284e418a58" source = "git+https://github.com/fluencelabs/interface-types?branch=byte_array#b65b34b0f627b3da5cd5761fe309cefc4980449b"
dependencies = [ dependencies = [
"nom", "nom",
"serde", "serde",

View File

@ -29,10 +29,51 @@ use std::convert::TryInto;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use crate::faas_interface::FaaSFunctionSignature; use crate::faas_interface::FaaSFunctionSignature;
use std::collections::HashSet;
// TODO: remove and use mutex instead // TODO: remove and use mutex instead
unsafe impl Send for FluenceFaaS {} unsafe impl Send for FluenceFaaS {}
/// Strategy for module loading: either `All`, or only those specified in `Named`
pub enum ModulesLoadStrategy<'a> {
All,
Named(&'a HashSet<String>),
}
impl<'a> ModulesLoadStrategy<'a> {
#[inline]
/// Returns true if `module` should be loaded.
pub fn should_load(&self, module: &str) -> bool {
match self {
ModulesLoadStrategy::All => true,
ModulesLoadStrategy::Named(set) => set.contains(module),
}
}
#[inline]
/// Returns the number of modules that must be loaded.
pub fn required_modules_len(&self) -> usize {
match self {
ModulesLoadStrategy::Named(set) => set.len(),
_ => 0,
}
}
#[inline]
/// Returns difference between required and loaded modules.
pub fn missing_modules<'s>(&self, loaded: impl Iterator<Item = &'s String>) -> Vec<&'s String> {
match self {
ModulesLoadStrategy::Named(set) => loaded.fold(vec![], |mut vec, module| {
if !set.contains(module) {
vec.push(module)
}
vec
}),
_ => <_>::default(),
}
}
}
pub struct FluenceFaaS { pub struct FluenceFaaS {
fce: FCE, fce: FCE,
@ -50,10 +91,9 @@ impl FluenceFaaS {
/// Creates FaaS from config deserialized from TOML. /// Creates FaaS from config deserialized from TOML.
pub fn with_raw_config(config: RawCoreModulesConfig) -> Result<Self> { pub fn with_raw_config(config: RawCoreModulesConfig) -> Result<Self> {
let config = crate::misc::from_raw_config(config)?; let config = crate::misc::from_raw_config(config)?;
let modules = config let modules = config.core_modules_dir.as_ref().map_or(Ok(vec![]), |dir| {
.core_modules_dir Self::load_modules(dir, ModulesLoadStrategy::All)
.as_ref() })?;
.map_or(Ok(vec![]), |dir| Self::load_modules(dir))?;
Self::with_modules(modules, config) Self::with_modules(modules, config)
} }
@ -80,29 +120,63 @@ impl FluenceFaaS {
}) })
} }
/// Searches for modules in `config.core_modules_dir`, loads only those in the `names` set
pub fn with_module_names<C>(names: &HashSet<String>, config: C) -> Result<Self>
where
C: TryInto<CoreModulesConfig>,
FaaSError: From<C::Error>,
{
let config = config.try_into()?;
let modules = config.core_modules_dir.as_ref().map_or(Ok(vec![]), |dir| {
Self::load_modules(dir, ModulesLoadStrategy::Named(names))
})?;
Self::with_modules::<_, CoreModulesConfig>(modules, config)
}
/// Loads modules from a directory at a given path. Non-recursive, ignores subdirectories. /// Loads modules from a directory at a given path. Non-recursive, ignores subdirectories.
fn load_modules(core_modules_dir: &str) -> Result<Vec<(String, Vec<u8>)>> { fn load_modules(
core_modules_dir: &str,
modules: ModulesLoadStrategy,
) -> Result<Vec<(String, Vec<u8>)>> {
use FaaSError::IOError; use FaaSError::IOError;
let mut dir_entries = fs::read_dir(core_modules_dir) let mut dir_entries = fs::read_dir(core_modules_dir)
.map_err(|e| IOError(format!("{}: {}", core_modules_dir, e)))?; .map_err(|e| IOError(format!("{}: {}", core_modules_dir, e)))?;
dir_entries.try_fold(vec![], |mut vec, entry| { let loaded = dir_entries.try_fold(vec![], |mut vec, entry| {
let entry = entry?; let entry = entry?;
let path = entry.path(); let path = entry.path();
if !path.is_dir() { // Skip directories
if path.is_dir() {
return Ok(vec);
}
let module_name = path let module_name = path
.file_name() .file_name()
.ok_or_else(|| IOError(format!("No file name in path {:?}", path)))? .ok_or_else(|| IOError(format!("No file name in path {:?}", path)))?
.to_os_string() .to_os_string()
.into_string() .into_string()
.map_err(|name| IOError(format!("invalid file name: {:?}", name)))?; .map_err(|name| IOError(format!("invalid file name: {:?}", name)))?;
if modules.should_load(&module_name) {
let module_bytes = fs::read(path)?; let module_bytes = fs::read(path)?;
vec.push((module_name, module_bytes)) vec.push((module_name, module_bytes));
} }
Ok(vec) Result::Ok(vec)
}) })?;
if modules.required_modules_len() > loaded.len() {
let loaded = loaded.iter().map(|(n, _)| n);
let not_found = modules.missing_modules(loaded);
return Err(FaaSError::ConfigParseError(format!(
"the following modules were not found: {:?}",
not_found
)));
}
Ok(loaded)
} }
/// Executes provided Wasm code in the internal environment (with access to module exports). /// Executes provided Wasm code in the internal environment (with access to module exports).