Use spawn_blocking for load_module

This commit is contained in:
Richard Feldman 2019-12-18 07:28:36 -05:00
parent 9c87d6aff8
commit efb0104adc
2 changed files with 12 additions and 9 deletions

View File

@ -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.

View File

@ -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<str>,
tx: Sender<DepNames>,
@ -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<DepNames>,
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