diff --git a/src/std_system.rs b/src/std_system.rs index 0f62155..4ef847b 100644 --- a/src/std_system.rs +++ b/src/std_system.rs @@ -73,7 +73,7 @@ async fn call_rpc_async, S: System>(context: &NetsBloxConte pub struct StdSystem>> { config: Config, context: Arc, - client: Arc, + client: reqwest::Client, rng: Mutex, clock: Arc, @@ -93,8 +93,9 @@ impl>> StdSystem { } /// Initializes a new instance of [`StdSystem`] targeting the given NetsBlox server base url, e.g., `https://cloud.netsblox.org`. pub async fn new_async(base_url: String, project_name: Option<&str>, config: Config, clock: Arc) -> Self { + let client = reqwest::Client::builder().build().unwrap(); let services_url = { - let configuration = reqwest::get(format!("{base_url}/configuration")).await.unwrap().json::>().await.unwrap(); + let configuration = client.get(format!("{base_url}/configuration")).send().await.unwrap().json::>().await.unwrap(); let services_hosts = configuration["servicesHosts"].as_array().unwrap(); services_hosts[0].as_object().unwrap().get("url").unwrap().as_str().unwrap().to_owned() }; @@ -111,13 +112,14 @@ impl>> StdSystem { }; let message_replies = Arc::new(Mutex::new(Default::default())); - let (message_sender, message_receiver, message_injector) = { + let (message_sender, message_receiver, message_injector, ws_finish_flag) = { let (base_url, client_id, project_name, message_replies) = (context.base_url.clone(), context.client_id.clone(), context.project_name.clone(), message_replies.clone()); let (out_sender, out_receiver) = channel(); let (in_sender, in_receiver) = channel(); + let finish_flag = Arc::new(()); #[tokio::main(flavor = "multi_thread", worker_threads = 1)] - async fn handler(base_url: String, client_id: String, project_name: String, message_replies: Arc>>, out_receiver: Receiver, in_sender: Sender) { + async fn handler(base_url: String, client_id: String, project_name: String, message_replies: Arc>>, out_receiver: Receiver, in_sender: Sender, finish_flag: Arc<()>) { let ws_url = format!("{}/network/{client_id}/connect", if let Some(x) = base_url.strip_prefix("http") { format!("ws{x}") } else { format!("wss://{base_url}") }); let (ws, _) = tokio_tungstenite::connect_async(ws_url).await.unwrap(); let (mut ws_sender, ws_receiver) = ws.split(); @@ -179,6 +181,7 @@ impl>> StdSystem { }); ws_sender_sender.send(Message::Text(json!({ "type": "set-uuid", "clientId": client_id }).to_string())).await.unwrap(); + drop(finish_flag); let src_id = format!("{project_name}@{client_id}#vm"); fn resolve_targets<'a>(targets: &'a mut [String], src_id: &String) -> &'a mut [String] { @@ -218,12 +221,16 @@ impl>> StdSystem { } } let in_sender_clone = in_sender.clone(); - thread::spawn(move || handler(base_url, client_id, project_name, message_replies, out_receiver, in_sender_clone)); + let finish_flag_clone = finish_flag.clone(); + thread::spawn(move || handler(base_url, client_id, project_name, message_replies, out_receiver, in_sender_clone, finish_flag_clone)); - (out_sender, in_receiver, in_sender) + (out_sender, in_receiver, in_sender, Arc::downgrade(&finish_flag)) }; - let client = Arc::new(reqwest::Client::builder().build().unwrap()); + while ws_finish_flag.upgrade().is_some() { + tokio::time::sleep(Duration::from_millis(10)).await; + } + let meta = client.post(format!("{}/projects/", context.base_url)) .json(&json!({ "clientId": context.client_id, "name": context.project_name })) .send().await.unwrap() @@ -246,7 +253,7 @@ impl>> StdSystem { let (sender, receiver) = channel(); #[tokio::main(flavor = "multi_thread", worker_threads = 1)] - async fn handler>>(client: Arc, context: Arc, receiver: Receiver>>) { + async fn handler>>(client: reqwest::Client, context: Arc, receiver: Receiver>>) { while let Ok(request) = receiver.recv() { let (client, context) = (client.clone(), context.clone()); tokio::spawn(async move {