From efb0104adcdebcc08dc9d5579d9490ea538b5da2 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Wed, 18 Dec 2019 07:28:36 -0500 Subject: [PATCH 1/3] Use spawn_blocking for load_module --- Cargo.toml | 2 +- src/load/mod.rs | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 115ab140ea..33c7de49f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ petgraph = { version = "0.4.5", optional = true } im = "14.0.0" # im and im-rc should always have the same version! im-rc = "14.0.0" # im and im-rc should always have the same version! wyhash = "0.3" -tokio = { version = "0.2", features = ["fs", "sync", "rt-threaded"] } +tokio = { version = "0.2", features = ["blocking", "fs", "sync", "rt-threaded"] } bumpalo = "2.6" # NOTE: Breaking API changes get pushed directly to this Inkwell branch, so be # very careful when running `cargo update` to get a new revision into Cargo.lock. diff --git a/src/load/mod.rs b/src/load/mod.rs index 9e4d786ff9..3c9c236c93 100644 --- a/src/load/mod.rs +++ b/src/load/mod.rs @@ -16,11 +16,12 @@ use crate::types::Constraint; use crate::unify::Problems; use bumpalo::Bump; use futures::future::join_all; +use std::fs::read_to_string; use std::io; use std::path::{Path, PathBuf}; use std::sync::Arc; -use tokio::fs::read_to_string; use tokio::sync::mpsc::{self, Receiver, Sender}; +use tokio::task::spawn_blocking; #[derive(Debug)] pub struct Loaded { @@ -90,8 +91,7 @@ pub async fn load<'a>( let main_tx = tx.clone(); let arc_var_store = Arc::new(VarStore::new(vars_created)); let var_store = Arc::clone(&arc_var_store); - let handle = - tokio::spawn(async move { load_filename(&env, filename, main_tx, &var_store).await }); + let handle = tokio::spawn(async move { load_filename(&env, filename, main_tx, &var_store) }); let requested_module = handle .await @@ -118,7 +118,10 @@ pub async fn load<'a>( let tx = tx.clone(); let var_store = Arc::clone(&arc_var_store); - tokio::spawn(async move { load_module(&env, dep, tx, &var_store).await }) + // Use spawn_blocking here because we're canonicalizing these in + // parallel, and canonicalization can potentially block the + // executor for awhile. + spawn_blocking(move || load_module(&env, dep, tx, &var_store)) })) .await; @@ -142,7 +145,7 @@ pub async fn load<'a>( } } -async fn load_module( +fn load_module( env: &Env, module_name: Box, tx: Sender, @@ -160,16 +163,16 @@ async fn load_module( // End with .roc filename.set_extension("roc"); - load_filename(env, filename, tx, var_store).await + load_filename(env, filename, tx, var_store) } -async fn load_filename( +fn load_filename( env: &Env, filename: PathBuf, tx: Sender, var_store: &VarStore, ) -> LoadedModule { - match read_to_string(&filename).await { + match read_to_string(&filename) { Ok(src) => { let arena = Bump::new(); // TODO instead of env.arena.alloc(src), we should create a new buffer From d398f715d64e26c043d163c28ba5be5685c544ce Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Wed, 18 Dec 2019 07:33:10 -0500 Subject: [PATCH 2/3] Follow clippy's advice --- src/load/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/load/mod.rs b/src/load/mod.rs index 3c9c236c93..97d11c7934 100644 --- a/src/load/mod.rs +++ b/src/load/mod.rs @@ -121,7 +121,7 @@ pub async fn load<'a>( // Use spawn_blocking here because we're canonicalizing these in // parallel, and canonicalization can potentially block the // executor for awhile. - spawn_blocking(move || load_module(&env, dep, tx, &var_store)) + spawn_blocking(move || load_module(&env, &dep, tx, &var_store)) })) .await; @@ -147,7 +147,7 @@ pub async fn load<'a>( fn load_module( env: &Env, - module_name: Box, + module_name: &str, tx: Sender, var_store: &VarStore, ) -> LoadedModule { From 12cd440284d628110a63658893d28273b43d68bc Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Wed, 18 Dec 2019 07:40:25 -0500 Subject: [PATCH 3/3] Use spawn_blocking for load() --- src/load/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/load/mod.rs b/src/load/mod.rs index 97d11c7934..97956f191e 100644 --- a/src/load/mod.rs +++ b/src/load/mod.rs @@ -91,8 +91,10 @@ pub async fn load<'a>( let main_tx = tx.clone(); let arc_var_store = Arc::new(VarStore::new(vars_created)); let var_store = Arc::clone(&arc_var_store); - let handle = tokio::spawn(async move { load_filename(&env, filename, main_tx, &var_store) }); + // Use spawn_blocking here so that we can proceed to the recv() loop + // while this is doing blocking work like reading and parsing the file. + let handle = spawn_blocking(move || load_filename(&env, filename, main_tx, &var_store)); let requested_module = handle .await .unwrap_or_else(|err| panic!("Unable to load requested module: {:?}", err));