Skip to content

Commit

Permalink
Merge pull request #10 from metacall/fix/async-await-compilation
Browse files Browse the repository at this point in the history
Fix/async await compilation
  • Loading branch information
viferga authored Sep 12, 2024
2 parents bb1545b + b69e9bd commit 329a788
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 100 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

Empty file.
1 change: 0 additions & 1 deletion crates/metassr-build/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pub mod bundler;
pub mod client;
pub mod server;
pub(crate) mod shared;
Expand Down
4 changes: 0 additions & 4 deletions crates/metassr-build/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ use std::{
ffi::OsStr,
fs,
path::{Path, PathBuf},
thread::sleep,
time::Duration,
};
use targets::TargetsGenerator;

Expand Down Expand Up @@ -88,8 +86,6 @@ impl Build for ServerSideBuilder {
return Err(anyhow!("Bundling failed: {e}"));
}

// TODO: find a solution to remove this line
sleep(Duration::from_secs(1));
let dist = DistDir::new(&self.dist_path)?.analyze()?;

let manifest =
Expand Down
37 changes: 5 additions & 32 deletions crates/metassr-build/src/server/renderer/head.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,13 @@
use anyhow::{anyhow, Result};
use lazy_static::lazy_static;
use metacall::{loaders, metacall_no_arg};
use metassr_utils::cache_dir::CacheDir;
use std::{
collections::HashMap, ffi::OsStr, path::PathBuf, sync::Mutex, thread::sleep, time::Duration,
};
use metassr_utils::{cache_dir::CacheDir, checker::CheckerState};
use std::{collections::HashMap, ffi::OsStr, path::PathBuf, sync::Mutex};

use metassr_bundler::WebBundler;

lazy_static! {
static ref IS_HEAD_SCRIPT_LOADED: Mutex<HeadSciptLoadingState> =
Mutex::new(HeadSciptLoadingState::default());
}

/// A detector for if the head is loaded or not.
#[derive(Debug)]
pub struct HeadSciptLoadingState(bool);

impl HeadSciptLoadingState {
pub fn new() -> Self {
Self(false)
}
pub fn loaded(&mut self) {
self.0 = true
}
pub fn is_loaded(&self) -> bool {
self.0
}
}

impl Default for HeadSciptLoadingState {
fn default() -> Self {
Self::new()
}
static ref IS_HEAD_SCRIPT_LOADED: Mutex<CheckerState> = Mutex::new(CheckerState::default());
}

pub struct HeadRenderer {
Expand All @@ -53,18 +28,16 @@ impl HeadRenderer {

pub fn render(&mut self, bundler: bool) -> Result<String> {
let mut guard = IS_HEAD_SCRIPT_LOADED.lock().unwrap();
if !guard.is_loaded() {
if !guard.is_true() {
if bundler {
self.bundle()?;
// TODO: remove this line
sleep(Duration::from_millis(500));
}

let _ = loaders::from_single_file(
"node",
format!("{}/head.js", self.cache_dir.dir_path().display()),
);
guard.loaded()
guard.make_true()
}
drop(guard);

Expand Down
1 change: 1 addition & 0 deletions crates/metassr-bundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ lazy_static = "1.5.0"
metacall = "0.4.1"
metassr-utils = { path = "../metassr-utils" }
serde_json = "1.0.128"
tracing = "0.1.40"
47 changes: 20 additions & 27 deletions crates/metassr-bundler/src/bundle.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
const { rspack } = require('@rspack/core');
const path = require("path");
const path = require('path');

function safelyParseJSON(json) {
let parsed

try {
parsed = JSON.parse(json)
return JSON.parse(json)
} catch (_) {
parsed = undefined
return undefined
}

return parsed // Could be undefined!
}

let config = {

output: {
filename: "[name].js",
filename: '[name].js',
library: {
type: "commonjs2",
type: 'commonjs2',
},
publicPath: ""
publicPath: ''
},
resolve: {
extensions: ['.js', '.jsx', '.tsx', '.ts']
Expand All @@ -46,7 +42,7 @@ let config = {
preserveAllComments: false,
transform: {
react: {
runtime: "automatic",
runtime: 'automatic',
throwIfNamespace: true,
useBuiltins: false,
},
Expand All @@ -70,7 +66,7 @@ let config = {
},
transform: {
react: {
runtime: "automatic",
runtime: 'automatic',
throwIfNamespace: true,
useBuiltins: false,
},
Expand All @@ -89,9 +85,7 @@ let config = {
}
}



function web_bundling(entry, dist) {
async function web_bundling(entry, dist) {

const compiler = rspack(
{
Expand All @@ -111,19 +105,18 @@ function web_bundling(entry, dist) {

);

compiler.run((error, stats) => {
if (error) {
console.error(error);
process.exit(2);
}
if (stats && stats.hasErrors()) {
process.exitCode = 1;
}
if (!compiler || !stats) {
return;
}
return new Promise((resolve, reject) => {
return compiler.run((error, stats) => {
if (error) {
reject(error.message);
}

if (error || stats?.hasErrors()) {
reject(stats.toString("errors-only"));
}
resolve(0);
});
});

}

module.exports = {
Expand Down
90 changes: 63 additions & 27 deletions crates/metassr-bundler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
use anyhow::{anyhow, Result};
use lazy_static::lazy_static;
use metacall::{loaders, metacall, MetacallNull};
use std::{collections::HashMap, ffi::OsStr, marker::Sized, path::Path, sync::Mutex};
use metacall::{loaders, metacall, MetacallFuture, MetacallValue};
use metassr_utils::checker::CheckerState;
use std::{
collections::HashMap,
ffi::OsStr,
marker::Sized,
path::Path,
sync::{Arc, Condvar, Mutex},
};
use tracing::error;

lazy_static! {
static ref IS_BUNDLING_SCRIPT_LOADED: Mutex<BundleSciptLoadingState> =
Mutex::new(BundleSciptLoadingState::new());
/// A detector for if the bundling script `./bundle.js` is loaded or not. It is used to solve multiple loading script error in metacall.
static ref IS_BUNDLING_SCRIPT_LOADED: Mutex<CheckerState> = Mutex::new(CheckerState::new());

/// A simple checker to check if the bundling function is done or not. It is used to block the program until bundling done.
static ref IS_COMPLIATION_WAIT: Arc<CompilationWait> = Arc::new(CompilationWait::default());
}
static BUILD_SCRIPT: &str = include_str!("./bundle.js");
const BUNDLING_FUNC: &str = "web_bundling";

/// A detector for if the bundling script `./bundle.js` is loaded or not.
#[derive(Debug)]
pub struct BundleSciptLoadingState(bool);

impl BundleSciptLoadingState {
pub fn new() -> Self {
Self(false)
}
pub fn loaded(&mut self) {
self.0 = true
}
pub fn is_loaded(&self) -> bool {
self.0
}
/// A simple struct for compilation wait of the bundling function.
struct CompilationWait {
checker: Mutex<CheckerState>,
cond: Condvar,
}

impl Default for BundleSciptLoadingState {
impl Default for CompilationWait {
fn default() -> Self {
Self::new()
Self {
checker: Mutex::new(CheckerState::with(false)),
cond: Condvar::new(),
}
}
}

Expand Down Expand Up @@ -56,24 +60,56 @@ impl<'a> WebBundler<'a> {
}
pub fn exec(&self) -> Result<()> {
let mut guard = IS_BUNDLING_SCRIPT_LOADED.lock().unwrap();
if !guard.is_loaded() {
if !guard.is_true() {
if let Err(e) = loaders::from_memory("node", BUILD_SCRIPT) {
return Err(anyhow!("Cannot load bundling script: {e:?}"));
}
guard.loaded();
guard.make_true();
}
drop(guard);

if let Err(e) = metacall::<MetacallNull>(

fn resolve(_: Box<dyn MetacallValue>, _: Box<dyn MetacallValue>) {
let compilation_wait = &*Arc::clone(&IS_COMPLIATION_WAIT);
let mut started = compilation_wait.checker.lock().unwrap();

started.make_true();
// We notify the condvar that the value has changed
compilation_wait.cond.notify_one();
}

fn reject(err: Box<dyn MetacallValue>, _: Box<dyn MetacallValue>) {
let compilation_wait = &*Arc::clone(&IS_COMPLIATION_WAIT);
let mut started = compilation_wait.checker.lock().unwrap();

error!("Bundling rejected: {err:?}");

started.make_true();
// We notify the condvar that the value has changed
compilation_wait.cond.notify_one();
}

let future = metacall::<MetacallFuture>(
BUNDLING_FUNC,
[
serde_json::to_string(&self.targets)?,
self.dist_path.to_str().unwrap().to_owned(),
],
) {
return Err(anyhow!("Cannot running {BUNDLING_FUNC}(): {e:?}"));
)
.unwrap();

future.then(resolve).catch(reject).await_fut();

// Wait for the thread to start up.
let compilation_wait = Arc::clone(&IS_COMPLIATION_WAIT);

let mut started = compilation_wait.checker.lock().unwrap();

// Waiting till future done
while !started.is_true() {
started = Arc::clone(&IS_COMPLIATION_WAIT).cond.wait(started).unwrap();
}

// Reset checker
started.make_false();
Ok(())
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/metassr-create/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl Creator {
}
}
pub fn generate(&self) -> Result<()> {
let template = self.template.load(&self)?;
let template = self.template.load(self)?;
let root = PathBuf::from(&self.project_name);

if root.exists() {
Expand Down
30 changes: 30 additions & 0 deletions crates/metassr-utils/src/checker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/// A simple checker state
#[derive(Debug)]
pub struct CheckerState(bool);
impl CheckerState {
pub fn new() -> Self {
Self(false)
}

pub fn with(state: bool) -> Self {
Self(state)
}

pub fn make_true(&mut self) {
self.0 = true
}

pub fn make_false(&mut self) {
self.0 = false
}

pub fn is_true(&self) -> bool {
self.0
}
}

impl Default for CheckerState {
fn default() -> Self {
Self::new()
}
}
1 change: 1 addition & 0 deletions crates/metassr-utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod cache_dir;
pub mod checker;
pub mod dist_analyzer;
pub mod rand;
pub mod src_analyzer;
Expand Down
7 changes: 1 addition & 6 deletions metassr-cli/src/cli/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ use metassr_build::server;

use metassr_build::{client::ClientBuilder, server::ServerSideBuilder, traits::Build};

use std::{
thread::sleep,
time::{Duration, Instant},
};
use std::time::Instant;

use tracing::{debug, error};

Expand All @@ -38,8 +35,6 @@ impl Exec for Builder {
return Err(anyhow!("Couldn't continue building process."));
}

// TODO: find a solution to remove this
sleep(Duration::from_secs(1));

if let Err(e) = ServerSideBuilder::new("", &self.out_dir, self._type.into())?.build() {
error!(
Expand Down
4 changes: 2 additions & 2 deletions metassr-cli/src/cli/creator.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clap::ValueEnum;
use metassr_create;
use metassr_create::Creator as MetassrCreator;
use std::{fmt::Display, str::FromStr};
use tracing::{error, info};

Expand Down Expand Up @@ -30,7 +30,7 @@ impl Creator {

impl Exec for Creator {
fn exec(&self) -> anyhow::Result<()> {
match metassr_create::Creator::new(
match MetassrCreator::new(
&self.project_name,
&self.version,
&self.description,
Expand Down

0 comments on commit 329a788

Please sign in to comment.