libraries can now work threaded if they wish (see http_requests). This means that multiple functions provided by one library can run at the same time (using thread(), see http.mers) and actually do the work they need to do simultaneously.

This commit is contained in:
mark
2023-05-09 22:11:13 +02:00
parent 9b92c5b353
commit a7bb3e67fa
13 changed files with 1127 additions and 518 deletions

View File

@@ -1,89 +1,139 @@
use mers_libs::{MyLib, MyLibTask, VDataEnum, VSingleType, VType};
use mers_libs::prelude::*;
fn main() {
let (mut my_lib, mut run) = MyLib::new(
"HTTP requests for MERS".to_string(),
let mut my_lib = MyLib::new(
"http".to_string(), // "HTTP requests for MERS".to_string(),
(0, 0),
"basic HTTP functionality for mers. warning: this is fully single-threaded.".to_string(),
vec![(
"http_get".to_string(),
vec![VSingleType::String.to()],
VType {
types: vec![
VSingleType::String,
VSingleType::EnumVariantS(
format!("Err"),
"desc".to_string(), // "basic HTTP functionality for mers. warning: this is fully single-threaded.".to_string(),
vec![
// http_get
(
"http_get".to_string(),
vec![
// (String) -> String/Err(ErrBuildingRequest(String)/ErrGettingResponseText(String))
(
vec![VSingleType::String.to()],
VType {
types: vec![
VSingleType::String,
VSingleType::EnumVariantS(
format!("ErrBuildingRequest"),
VSingleType::String.to(),
),
VSingleType::EnumVariantS(
format!("ErrGettingResponseText"),
VSingleType::String.to(),
format!("Err"),
VType {
types: vec![
VSingleType::EnumVariantS(
format!("ErrBuildingRequest"),
VSingleType::String.to(),
),
VSingleType::EnumVariantS(
format!("ErrGettingResponseText"),
VSingleType::String.to(),
),
],
},
),
],
},
),
],
},
)],
),
],
);
let mut stdin = std::io::stdin().lock();
let mut stdout = std::io::stdout().lock();
let mut err_general = 0;
let mut err_building_request = 0;
let mut err_getting_response_text = 0;
loop {
run = match my_lib.run(run, &mut stdin, &mut stdout) {
MyLibTask::None(v) => v,
MyLibTask::FinishedInit(v) => {
err_general = my_lib.get_enum("Err").unwrap();
err_building_request = my_lib.get_enum("ErrBuildingRequest").unwrap();
err_getting_response_text = my_lib.get_enum("ErrGettingResponseText").unwrap();
v
}
MyLibTask::RunFunction(f) => {
let return_value = match f.function {
0 => {
// http_get
if let VDataEnum::String(url) = &f.args[0].data {
match reqwest::blocking::get(url) {
Ok(response) => match response.text() {
Ok(text) => VDataEnum::String(text).to(),
Err(e) => VDataEnum::EnumVariant(
err_general,
Box::new(
VDataEnum::EnumVariant(
err_getting_response_text,
Box::new(VDataEnum::String(e.to_string()).to()),
)
.to(),
),
)
.to(),
},
Err(e) => VDataEnum::EnumVariant(
err_general,
Box::new(
VDataEnum::EnumVariant(
err_building_request,
Box::new(VDataEnum::String(e.to_string()).to()),
)
.to(),
),
let err_general = my_lib
.get_enums()
.iter()
.find(|(name, _)| name.as_str() == "Err")
.unwrap()
.1;
let err_building_request = my_lib
.get_enums()
.iter()
.find(|(name, _)| name.as_str() == "ErrBuildingRequest")
.unwrap()
.1;
let err_getting_response_text = my_lib
.get_enums()
.iter()
.find(|(name, _)| name.as_str() == "ErrGettingResponseText")
.unwrap()
.1;
my_lib.callbacks.run_function.consuming = Some(Box::new(move |msg| {
if let VDataEnum::String(url) = &msg.msg.args[0].data {
let url = url.clone();
std::thread::spawn(move || {
let r = match reqwest::blocking::get(url) {
Ok(response) => match response.text() {
Ok(text) => VDataEnum::String(text).to(),
Err(e) => VDataEnum::EnumVariant(
err_general,
Box::new(
VDataEnum::EnumVariant(
err_getting_response_text,
Box::new(VDataEnum::String(e.to_string()).to()),
)
.to(),
}
} else {
unreachable!()
}
}
_ => unreachable!(),
),
)
.to(),
},
Err(e) => VDataEnum::EnumVariant(
err_general,
Box::new(
VDataEnum::EnumVariant(
err_building_request,
Box::new(VDataEnum::String(e.to_string()).to()),
)
.to(),
),
)
.to(),
};
f.done(&mut stdout, return_value)
}
msg.respond(r)
});
} else {
unreachable!()
}
}
}));
// because we handle all callbacks, this never returns Err(unhandeled message).
// it returns Ok(()) if mers exits (i/o error in stdin/stdout), so we also exit if that happens.
my_lib.get_next_unhandled_message().unwrap();
}
// fn run_function(f: ()) {
// let return_value = match f.function {
// 0 => {
// // http_get
// if let VDataEnum::String(url) = &f.args[0].data {
// match reqwest::blocking::get(url) {
// Ok(response) => match response.text() {
// Ok(text) => VDataEnum::String(text).to(),
// Err(e) => VDataEnum::EnumVariant(
// err_general,
// Box::new(
// VDataEnum::EnumVariant(
// err_getting_response_text,
// Box::new(VDataEnum::String(e.to_string()).to()),
// )
// .to(),
// ),
// )
// .to(),
// },
// Err(e) => VDataEnum::EnumVariant(
// err_general,
// Box::new(
// VDataEnum::EnumVariant(
// err_building_request,
// Box::new(VDataEnum::String(e.to_string()).to()),
// )
// .to(),
// ),
// )
// .to(),
// }
// } else {
// unreachable!()
// }
// }
// _ => unreachable!(),
// };
// f.done(&mut stdout, return_value)
// }