From ff99e5a8f6f02cc9a3eb193d8c84c9633cff9aac Mon Sep 17 00:00:00 2001 From: Kozlov Maxim Date: Fri, 4 Aug 2023 16:51:30 +0600 Subject: [PATCH] added concurrent HTTP --- Cargo.toml | 2 ++ src/ffi/connection.rs | 8 ++++---- src/my_add_in/func.rs | 46 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index aa42dcc..51b0251 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [lib] crate-type = ["cdylib"] +# from https://github.com/johnthagen/min-sized-rust [profile.release] opt-level = "z" # Optimize for size. lto = true # Enable Link Time Optimization @@ -14,6 +15,7 @@ panic = "abort" # Abort on panic strip = true # Automatically strip symbols from the binary. [dependencies] +base64 = "0.21.2" color-eyre = "0.6.2" log = "0.4.19" log4rs = "1.2.0" diff --git a/src/ffi/connection.rs b/src/ffi/connection.rs index b195288..717006d 100644 --- a/src/ffi/connection.rs +++ b/src/ffi/connection.rs @@ -1,6 +1,6 @@ use std::ffi::{c_long, c_ushort}; -use super::{types::TVariant, utils::os_string}; +use super::{types::TVariant, utils::os_string_nil}; #[repr(C)] struct ConnectionVTable { @@ -64,9 +64,9 @@ impl Connection { pub fn external_event(&self, caller: &str, name: &str, data: &str) -> bool { unsafe { - let caller_ptr = os_string(caller).as_mut_ptr(); - let name_ptr = os_string(name).as_mut_ptr(); - let data_ptr = os_string(data).as_mut_ptr(); + let caller_ptr = os_string_nil(caller).as_mut_ptr(); + let name_ptr = os_string_nil(name).as_mut_ptr(); + let data_ptr = os_string_nil(data).as_mut_ptr(); (self.vptr1.external_event)(self, caller_ptr, name_ptr, data_ptr) } } diff --git a/src/my_add_in/func.rs b/src/my_add_in/func.rs index 9cffdad..31454c1 100644 --- a/src/my_add_in/func.rs +++ b/src/my_add_in/func.rs @@ -2,6 +2,7 @@ use super::MyAddInDescription; use crate::add_in::ComponentFuncDescription; use crate::ffi::utils::os_string; use crate::ffi::{types::ParamValue, utils::from_os_string}; +use base64::{engine::general_purpose, Engine as _}; use color_eyre::eyre::{eyre, Result}; use log::LevelFilter; use log4rs::{ @@ -47,6 +48,14 @@ impl MyAddInDescription { ), callback: Self::fetch, }, + FunctionListElement { + description: ComponentFuncDescription::new::<1>( + &["ПолучитьХэТэТэПэПараллельно", "FetchHTTPConcurrently"], + true, + &[None], + ), + callback: Self::concurrent_fetch, + }, FunctionListElement { description: ComponentFuncDescription::new::<1>( &[("ИнициализироватьЛоггер"), ("InitLogger")], @@ -103,6 +112,43 @@ impl MyAddInDescription { Ok(Some(ParamValue::Str(os_string(&body)))) } + fn concurrent_fetch( + &mut self, + params: &[ParamValue], + ) -> Result> { + let request_count = match params.get(0) { + Some(ParamValue::I32(val)) => *val, + _ => return Err(eyre!("Invalid parameter")), + }; + if request_count < 0 { + return Err(eyre!("Invalid parameter")); + } + let request_count = request_count as u64; + + let mut threads_handles = Vec::new(); + for _ in 0..request_count { + let handle = thread::spawn(move || { + let Ok(result) = ureq::post("https://echo.hoppscotch.io").send_string("smth") else {return Err(eyre!("Failed to fetch"));}; + let Ok(body) = result.into_string() else { return Err(eyre!("Failed to get body"));}; + Ok(body) + }); + threads_handles.push(handle); + } + let results: Vec = threads_handles + .into_iter() + .map(|h| -> String { + let Ok(req_result) = + h.join() else { return format!("ERR")}; + let Ok(req_text) = req_result else { return format!("ERR")}; + let base64_text = + general_purpose::STANDARD_NO_PAD.encode(req_text); + base64_text + }) + .collect(); + + Ok(Some(ParamValue::Str(os_string(&results.join(";"))))) + } + fn init_logger( &mut self, params: &[ParamValue],