Skip to content

Commit

Permalink
Changes to allow plugins to be loaded in a multi-threaded manner (nus…
Browse files Browse the repository at this point in the history
…hell#1694)

* Changes to allow plugins to be loaded in a multi-threaded manner in order to decrease startup time.

* Ran rust fmt and clippy to find and fix first pass errors.
Updated launch.jason to make debugging easier in vscode.
Also added tasks.json so tasks like clippy can be ran easily.

* ran fmt again

* Delete launch.json

Remove IDE settings file

* Remove IDE settings file

* Ignore vscode IDE settings

* Cloned the context instead of Arc/Mutexing it.

Co-authored-by: Darren Schroeder <fdncred@hotmail.com>
Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com>
  • Loading branch information
3 people committed May 4, 2020
1 parent a996804 commit d2ac506
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 44 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -17,3 +17,6 @@ debian/nu/

# JetBrains' IDE items
.idea/*

# VSCode's IDE items
.vscode/*
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/nu-cli/Cargo.toml
Expand Up @@ -89,6 +89,7 @@ which = "3"
trash = { version = "1.0.0", optional = true }
clipboard = { version = "0.5", optional = true }
starship = { version = "0.39.0", optional = true }
rayon = "1.3.0"

[target.'cfg(unix)'.dependencies]
users = "0.10.0"
Expand Down
92 changes: 48 additions & 44 deletions crates/nu-cli/src/cli.rs
Expand Up @@ -26,6 +26,8 @@ use std::iter::Iterator;
use std::path::{Path, PathBuf};
use std::sync::atomic::Ordering;

use rayon::prelude::*;

fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), ShellError> {
let mut child = std::process::Command::new(path)
.stdin(std::process::Stdio::piped())
Expand Down Expand Up @@ -132,58 +134,60 @@ pub fn load_plugins(context: &mut Context) -> Result<(), ShellError> {

pattern.push(std::path::Path::new("nu_plugin_[a-z0-9][a-z0-9]*"));

match glob::glob_with(&pattern.to_string_lossy(), opts) {
Err(_) => {}
Ok(binaries) => {
for bin in binaries.filter_map(Result::ok) {
let bin_name = {
if let Some(name) = bin.file_name() {
match name.to_str() {
Some(raw) => raw,
None => continue,
}
} else {
continue;
let plugs: Vec<_> = glob::glob_with(&pattern.to_string_lossy(), opts)?
.filter_map(|x| x.ok())
.collect();

let _failures: Vec<_> = plugs
.par_iter()
.map(|path| {
let bin_name = {
if let Some(name) = path.file_name() {
match name.to_str() {
Some(raw) => raw,
None => "",
}
};
} else {
""
}
};

let is_valid_name = {
#[cfg(windows)]
{
bin_name
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.')
}
let is_valid_name = {
#[cfg(windows)]
{
bin_name
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.')
}

#[cfg(not(windows))]
{
bin_name
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '_')
}
};
#[cfg(not(windows))]
{
bin_name
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '_')
}
};

let is_executable = {
#[cfg(windows)]
{
bin_name.ends_with(".exe") || bin_name.ends_with(".bat")
}
let is_executable = {
#[cfg(windows)]
{
bin_name.ends_with(".exe") || bin_name.ends_with(".bat")
}

#[cfg(not(windows))]
{
true
}
};
#[cfg(not(windows))]
{
true
}
};

if is_valid_name && is_executable {
trace!("Trying {:?}", bin.display());
if is_valid_name && is_executable {
trace!("Trying {:?}", path.display());

// we are ok if this plugin load fails
let _ = load_plugin(&bin, context);
}
// we are ok if this plugin load fails
let _ = load_plugin(&path, &mut context.clone());
}
}
}
})
.collect();
}

Ok(())
Expand Down
1 change: 1 addition & 0 deletions crates/nu-errors/Cargo.toml
Expand Up @@ -25,6 +25,7 @@ getset = "0.1.0"
serde_yaml = "0.8"
toml = "0.5.6"
serde_json = "1.0.51"
glob = "0.3.0"

[build-dependencies]
nu-build = { version = "0.13.0", path = "../nu-build" }
6 changes: 6 additions & 0 deletions crates/nu-errors/src/lib.rs
Expand Up @@ -864,6 +864,12 @@ impl std::convert::From<Box<dyn std::error::Error + Send + Sync>> for ShellError
}
}

impl std::convert::From<glob::PatternError> for ShellError {
fn from(input: glob::PatternError) -> ShellError {
ShellError::untagged_runtime_error(format!("{:?}", input))
}
}

pub trait CoerceInto<U> {
fn coerce_into(self, operation: impl Into<String>) -> Result<U, ShellError>;
}
Expand Down

0 comments on commit d2ac506

Please sign in to comment.