diff --git a/Cargo.lock b/Cargo.lock index ce6076eab..c47655c27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6401,11 +6401,13 @@ dependencies = [ "anyhow", "async-trait", "cap-std", + "chrono", "clap 4.0.27", "futures", "hyper", "rmp-serde", "rocket", + "serde_json", "shuttle-common", "shuttle-proto", "shuttle-secrets", @@ -6442,7 +6444,6 @@ dependencies = [ "bincode", "cargo", "cargo_metadata", - "chrono", "crossbeam-channel", "futures", "hyper", diff --git a/cargo-shuttle/src/lib.rs b/cargo-shuttle/src/lib.rs index 2f5fab49f..2c2466269 100644 --- a/cargo-shuttle/src/lib.rs +++ b/cargo-shuttle/src/lib.rs @@ -383,6 +383,7 @@ impl Shuttle { "Building".bold().green(), working_directory.display() ); + let runtime = build_crate(working_directory, false, tx).await?; trace!("loading secrets"); @@ -403,7 +404,7 @@ impl Shuttle { let service_name = self.ctx.project_name().to_string(); - let (is_wasm, so_path) = match runtime { + let (is_wasm, bin_path) = match runtime { Runtime::Next(path) => (true, path), Runtime::Legacy(path) => (false, path), }; @@ -414,44 +415,54 @@ impl Shuttle { run_args.port + 1, )); - let get_runtime_executable = || { - let runtime_path = home::cargo_home() - .expect("failed to find cargo home dir") - .join("bin/shuttle-runtime"); - - if cfg!(debug_assertions) { - // Canonicalized path to shuttle-runtime for dev to work on windows - let path = std::fs::canonicalize(format!("{MANIFEST_DIR}/../runtime")) - .expect("path to shuttle-runtime does not exist or is invalid"); - - std::process::Command::new("cargo") - .arg("install") - .arg("shuttle-runtime") - .arg("--path") - .arg(path) - .output() - .expect("failed to install the shuttle runtime"); - } else { - // If the version of cargo-shuttle is different from shuttle-runtime, - // or it isn't installed, try to install shuttle-runtime from the production - // branch. - if let Err(err) = check_version(&runtime_path) { - trace!("{}", err); + let runtime_path = || { + if is_wasm { + let runtime_path = home::cargo_home() + .expect("failed to find cargo home dir") + .join("bin/shuttle-next"); + + if cfg!(debug_assertions) { + // Canonicalized path to shuttle-runtime for dev to work on windows + let path = std::fs::canonicalize(format!("{MANIFEST_DIR}/../runtime")) + .expect("path to shuttle-runtime does not exist or is invalid"); - trace!("installing shuttle-runtime"); + // TODO: Add --features next here when https://github.com/shuttle-hq/shuttle/pull/688 is merged std::process::Command::new("cargo") .arg("install") .arg("shuttle-runtime") - .arg("--git") - .arg("https://github.com/shuttle-hq/shuttle") - .arg("--branch") - .arg("production") + .arg("--path") + .arg(path) + .arg("--bin") + .arg("shuttle-next") .output() .expect("failed to install the shuttle runtime"); + } else { + // If the version of cargo-shuttle is different from shuttle-runtime, + // or it isn't installed, try to install shuttle-runtime from the production + // branch. + if let Err(err) = check_version(&runtime_path) { + trace!("{}", err); + + trace!("installing shuttle-runtime"); + // TODO: Add --features next here when https://github.com/shuttle-hq/shuttle/pull/688 is merged + std::process::Command::new("cargo") + .arg("install") + .arg("shuttle-runtime") + .arg("--bin") + .arg("shuttle-next") + .arg("--git") + .arg("https://github.com/shuttle-hq/shuttle") + .arg("--branch") + .arg("production") + .output() + .expect("failed to install the shuttle runtime"); + }; }; - }; - runtime_path + runtime_path + } else { + bin_path.clone() + } }; let (mut runtime, mut runtime_client) = runtime::start( @@ -459,7 +470,7 @@ impl Shuttle { runtime::StorageManagerType::WorkingDir(working_directory.to_path_buf()), &format!("http://localhost:{}", run_args.port + 1), run_args.port + 2, - get_runtime_executable, + runtime_path, ) .await .map_err(|err| { @@ -469,7 +480,7 @@ impl Shuttle { })?; let load_request = tonic::Request::new(LoadRequest { - path: so_path + path: bin_path .into_os_string() .into_string() .expect("to convert path to string"), diff --git a/codegen/src/shuttle_main/mod.rs b/codegen/src/shuttle_main/mod.rs index c8a03d1da..3b73f82a5 100644 --- a/codegen/src/shuttle_main/mod.rs +++ b/codegen/src/shuttle_main/mod.rs @@ -4,50 +4,32 @@ use quote::{quote, ToTokens}; use syn::{ parenthesized, parse::Parse, parse2, parse_macro_input, parse_quote, punctuated::Punctuated, spanned::Spanned, token::Paren, Attribute, Expr, FnArg, Ident, ItemFn, Pat, PatIdent, Path, - ReturnType, Signature, Stmt, Token, Type, + ReturnType, Signature, Stmt, Token, Type, TypePath, }; pub(crate) fn r#impl(_attr: TokenStream, item: TokenStream) -> TokenStream { let mut fn_decl = parse_macro_input!(item as ItemFn); - let wrapper = Wrapper::from_item_fn(&mut fn_decl); + let loader = Loader::from_item_fn(&mut fn_decl); let expanded = quote! { - #wrapper - - fn __binder( - service: Box, - addr: std::net::SocketAddr, - runtime: &shuttle_service::Runtime, - ) -> shuttle_service::ServeHandle { - use shuttle_service::Context; - runtime.spawn(async move { service.bind(addr).await.context("failed to bind service").map_err(Into::into) }) + #[tokio::main] + async fn main() { + shuttle_runtime::start(loader).await; } - #fn_decl - - #[no_mangle] - pub extern "C" fn _create_service() -> *mut shuttle_service::Bootstrapper { - let builder: shuttle_service::StateBuilder> = - |factory, runtime, logger| Box::pin(__shuttle_wrapper(factory, runtime, logger)); + #loader - let bootstrapper = shuttle_service::Bootstrapper::new( - builder, - __binder, - shuttle_service::Runtime::new().unwrap(), - ); - - let boxed = Box::new(bootstrapper); - Box::into_raw(boxed) - } + #fn_decl }; expanded.into() } -struct Wrapper { +struct Loader { fn_ident: Ident, fn_inputs: Vec, + fn_return: TypePath, } #[derive(Debug, PartialEq)] @@ -117,8 +99,8 @@ impl Parse for BuilderOption { } } -impl Wrapper { - pub(crate) fn from_item_fn(item_fn: &mut ItemFn) -> Self { +impl Loader { + pub(crate) fn from_item_fn(item_fn: &mut ItemFn) -> Option { let inputs: Vec<_> = item_fn .sig .inputs @@ -145,31 +127,40 @@ impl Wrapper { }) .collect(); - check_return_type(&item_fn.sig); - - Self { - fn_ident: item_fn.sig.ident.clone(), - fn_inputs: inputs, + if let Some(type_path) = check_return_type(item_fn.sig.clone()) { + Some(Self { + fn_ident: item_fn.sig.ident.clone(), + fn_inputs: inputs, + fn_return: type_path, + }) + } else { + None } } } -fn check_return_type(signature: &Signature) { - match &signature.output { - ReturnType::Default => emit_error!( - signature, - "shuttle_service::main functions need to return a service"; - hint = "See the docs for services with first class support"; - doc = "https://docs.rs/shuttle-service/latest/shuttle_service/attr.main.html#shuttle-supported-services" - ), - ReturnType::Type(_, r#type) => match r#type.as_ref() { - Type::Path(_) => {} - _ => emit_error!( - r#type, - "shuttle_service::main functions need to return a first class service or 'Result"; +fn check_return_type(signature: Signature) -> Option { + match signature.output { + ReturnType::Default => { + emit_error!( + signature, + "shuttle_service::main functions need to return a service"; hint = "See the docs for services with first class support"; doc = "https://docs.rs/shuttle-service/latest/shuttle_service/attr.main.html#shuttle-supported-services" - ), + ); + None + } + ReturnType::Type(_, r#type) => match *r#type { + Type::Path(path) => Some(path), + _ => { + emit_error!( + r#type, + "shuttle_service::main functions need to return a first class service or 'Result"; + hint = "See the docs for services with first class support"; + doc = "https://docs.rs/shuttle-service/latest/shuttle_service/attr.main.html#shuttle-supported-services" + ); + None + } }, } } @@ -196,9 +187,12 @@ fn attribute_to_builder(pat_ident: &PatIdent, attrs: Vec) -> syn::Res Ok(builder) } -impl ToTokens for Wrapper { +impl ToTokens for Loader { fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { let fn_ident = &self.fn_ident; + + let return_type = &self.fn_return; + let mut fn_inputs: Vec<_> = Vec::with_capacity(self.fn_inputs.len()); let mut fn_inputs_builder: Vec<_> = Vec::with_capacity(self.fn_inputs.len()); let mut fn_inputs_builder_options: Vec<_> = Vec::with_capacity(self.fn_inputs.len()); @@ -223,67 +217,32 @@ impl ToTokens for Wrapper { )) }; - let wrapper = quote! { - async fn __shuttle_wrapper( - #factory_ident: &mut dyn shuttle_service::Factory, - runtime: &shuttle_service::Runtime, - logger: shuttle_service::Logger, - ) -> Result, shuttle_service::Error> { + let loader = quote! { + async fn loader( + mut #factory_ident: shuttle_runtime::ProvisionerFactory, + logger: shuttle_runtime::Logger, + ) -> #return_type { use shuttle_service::Context; use shuttle_service::tracing_subscriber::prelude::*; #extra_imports - runtime.spawn_blocking(move || { - let filter_layer = - shuttle_service::tracing_subscriber::EnvFilter::try_from_default_env() - .or_else(|_| shuttle_service::tracing_subscriber::EnvFilter::try_new("INFO")) - .unwrap(); - - shuttle_service::tracing_subscriber::registry() - .with(filter_layer) - .with(logger) - .init(); // this sets the subscriber as the global default and also adds a compatibility layer for capturing `log::Record`s - }) - .await - .map_err(|e| { - if e.is_panic() { - let mes = e - .into_panic() - .downcast_ref::<&str>() - .map(|x| x.to_string()) - .unwrap_or_else(|| "panicked setting logger".to_string()); - - shuttle_service::Error::BuildPanic(mes) - } else { - shuttle_service::Error::Custom(shuttle_service::error::CustomError::new(e).context("failed to set logger")) - } - })?; - - #(let #fn_inputs = #fn_inputs_builder::new()#fn_inputs_builder_options.build(#factory_ident, runtime).await.context(format!("failed to provision {}", stringify!(#fn_inputs_builder)))?;)* - - runtime.spawn(async { - #fn_ident(#(#fn_inputs),*) - .await - .map(|ok| Box::new(ok) as Box) - }) - .await - .map_err(|e| { - if e.is_panic() { - let mes = e - .into_panic() - .downcast_ref::<&str>() - .map(|x| x.to_string()) - .unwrap_or_else(|| "panicked calling main".to_string()); - - shuttle_service::Error::BuildPanic(mes) - } else { - shuttle_service::Error::Custom(shuttle_service::error::CustomError::new(e).context("failed to call main")) - } - })? + let filter_layer = + shuttle_service::tracing_subscriber::EnvFilter::try_from_default_env() + .or_else(|_| shuttle_service::tracing_subscriber::EnvFilter::try_new("INFO")) + .unwrap(); + + shuttle_service::tracing_subscriber::registry() + .with(filter_layer) + .with(logger) + .init(); + + #(let #fn_inputs = #fn_inputs_builder::new()#fn_inputs_builder_options.build(&mut #factory_ident).await.context(format!("failed to provision {}", stringify!(#fn_inputs_builder)))?;)* + + #fn_ident(#(#fn_inputs),*).await } }; - wrapper.to_tokens(tokens); + loader.to_tokens(tokens); } } @@ -293,7 +252,7 @@ mod tests { use quote::quote; use syn::{parse_quote, Ident}; - use super::{Builder, BuilderOptions, Input, Wrapper}; + use super::{Builder, BuilderOptions, Input, Loader}; #[test] fn from_with_return() { @@ -301,7 +260,7 @@ mod tests { async fn simple() -> ShuttleAxum {} ); - let actual = Wrapper::from_item_fn(&mut input); + let actual = Loader::from_item_fn(&mut input).unwrap(); let expected_ident: Ident = parse_quote!(simple); assert_eq!(actual.fn_ident, expected_ident); @@ -310,65 +269,32 @@ mod tests { #[test] fn output_with_return() { - let input = Wrapper { + let input = Loader { fn_ident: parse_quote!(simple), fn_inputs: Vec::new(), + fn_return: parse_quote!(ShuttleSimple), }; let actual = quote!(#input); let expected = quote! { - async fn __shuttle_wrapper( - _factory: &mut dyn shuttle_service::Factory, - runtime: &shuttle_service::Runtime, - logger: shuttle_service::Logger, - ) -> Result, shuttle_service::Error> { + async fn loader( + mut _factory: shuttle_runtime::ProvisionerFactory, + logger: shuttle_runtime::Logger, + ) -> ShuttleSimple { use shuttle_service::Context; use shuttle_service::tracing_subscriber::prelude::*; - runtime.spawn_blocking(move || { - let filter_layer = - shuttle_service::tracing_subscriber::EnvFilter::try_from_default_env() - .or_else(|_| shuttle_service::tracing_subscriber::EnvFilter::try_new("INFO")) - .unwrap(); - - shuttle_service::tracing_subscriber::registry() - .with(filter_layer) - .with(logger) - .init(); - }) - .await - .map_err(|e| { - if e.is_panic() { - let mes = e - .into_panic() - .downcast_ref::<&str>() - .map(|x| x.to_string()) - .unwrap_or_else(|| "panicked setting logger".to_string()); - - shuttle_service::Error::BuildPanic(mes) - } else { - shuttle_service::Error::Custom(shuttle_service::error::CustomError::new(e).context("failed to set logger")) - } - })?; - - runtime.spawn(async { - simple() - .await - .map(|ok| Box::new(ok) as Box) - }) - .await - .map_err(|e| { - if e.is_panic() { - let mes = e - .into_panic() - .downcast_ref::<&str>() - .map(|x| x.to_string()) - .unwrap_or_else(|| "panicked calling main".to_string()); - - shuttle_service::Error::BuildPanic(mes) - } else { - shuttle_service::Error::Custom(shuttle_service::error::CustomError::new(e).context("failed to call main")) - } - })? + + let filter_layer = + shuttle_service::tracing_subscriber::EnvFilter::try_from_default_env() + .or_else(|_| shuttle_service::tracing_subscriber::EnvFilter::try_new("INFO")) + .unwrap(); + + shuttle_service::tracing_subscriber::registry() + .with(filter_layer) + .with(logger) + .init(); + + simple().await } }; @@ -381,7 +307,7 @@ mod tests { async fn complex(#[shuttle_shared_db::Postgres] pool: PgPool) -> ShuttleTide {} ); - let actual = Wrapper::from_item_fn(&mut input); + let actual = Loader::from_item_fn(&mut input).unwrap(); let expected_ident: Ident = parse_quote!(complex); let expected_inputs: Vec = vec![Input { ident: parse_quote!(pool), @@ -408,7 +334,7 @@ mod tests { #[test] fn output_with_inputs() { - let input = Wrapper { + let input = Loader { fn_ident: parse_quote!(complex), fn_inputs: vec![ Input { @@ -426,67 +352,33 @@ mod tests { }, }, ], + fn_return: parse_quote!(ShuttleComplex), }; let actual = quote!(#input); let expected = quote! { - async fn __shuttle_wrapper( - factory: &mut dyn shuttle_service::Factory, - runtime: &shuttle_service::Runtime, - logger: shuttle_service::Logger, - ) -> Result, shuttle_service::Error> { + async fn loader( + mut factory: shuttle_runtime::ProvisionerFactory, + logger: shuttle_runtime::Logger, + ) -> ShuttleComplex { use shuttle_service::Context; use shuttle_service::tracing_subscriber::prelude::*; use shuttle_service::ResourceBuilder; - runtime.spawn_blocking(move || { - let filter_layer = - shuttle_service::tracing_subscriber::EnvFilter::try_from_default_env() - .or_else(|_| shuttle_service::tracing_subscriber::EnvFilter::try_new("INFO")) - .unwrap(); - - shuttle_service::tracing_subscriber::registry() - .with(filter_layer) - .with(logger) - .init(); - }) - .await - .map_err(|e| { - if e.is_panic() { - let mes = e - .into_panic() - .downcast_ref::<&str>() - .map(|x| x.to_string()) - .unwrap_or_else(|| "panicked setting logger".to_string()); - - shuttle_service::Error::BuildPanic(mes) - } else { - shuttle_service::Error::Custom(shuttle_service::error::CustomError::new(e).context("failed to set logger")) - } - })?; - - let pool = shuttle_shared_db::Postgres::new().build(factory, runtime).await.context(format!("failed to provision {}", stringify!(shuttle_shared_db::Postgres)))?; - let redis = shuttle_shared_db::Redis::new().build(factory, runtime).await.context(format!("failed to provision {}", stringify!(shuttle_shared_db::Redis)))?; - - runtime.spawn(async { - complex(pool, redis) - .await - .map(|ok| Box::new(ok) as Box) - }) - .await - .map_err(|e| { - if e.is_panic() { - let mes = e - .into_panic() - .downcast_ref::<&str>() - .map(|x| x.to_string()) - .unwrap_or_else(|| "panicked calling main".to_string()); - - shuttle_service::Error::BuildPanic(mes) - } else { - shuttle_service::Error::Custom(shuttle_service::error::CustomError::new(e).context("failed to call main")) - } - })? + let filter_layer = + shuttle_service::tracing_subscriber::EnvFilter::try_from_default_env() + .or_else(|_| shuttle_service::tracing_subscriber::EnvFilter::try_new("INFO")) + .unwrap(); + + shuttle_service::tracing_subscriber::registry() + .with(filter_layer) + .with(logger) + .init(); + + let pool = shuttle_shared_db::Postgres::new().build(&mut factory).await.context(format!("failed to provision {}", stringify!(shuttle_shared_db::Postgres)))?; + let redis = shuttle_shared_db::Redis::new().build(&mut factory).await.context(format!("failed to provision {}", stringify!(shuttle_shared_db::Redis)))?; + + complex(pool, redis).await } }; @@ -541,7 +433,7 @@ mod tests { } ); - let actual = Wrapper::from_item_fn(&mut input); + let actual = Loader::from_item_fn(&mut input).unwrap(); let expected_ident: Ident = parse_quote!(complex); let mut expected_inputs: Vec = vec![Input { ident: parse_quote!(pool), @@ -568,7 +460,7 @@ mod tests { #[test] fn output_with_input_options() { - let mut input = Wrapper { + let mut input = Loader { fn_ident: parse_quote!(complex), fn_inputs: vec![Input { ident: parse_quote!(pool), @@ -577,6 +469,7 @@ mod tests { options: Default::default(), }, }], + fn_return: parse_quote!(ShuttleComplex), }; input.fn_inputs[0] @@ -592,62 +485,27 @@ mod tests { let actual = quote!(#input); let expected = quote! { - async fn __shuttle_wrapper( - factory: &mut dyn shuttle_service::Factory, - runtime: &shuttle_service::Runtime, - logger: shuttle_service::Logger, - ) -> Result, shuttle_service::Error> { + async fn loader( + mut factory: shuttle_runtime::ProvisionerFactory, + logger: shuttle_runtime::Logger, + ) -> ShuttleComplex { use shuttle_service::Context; use shuttle_service::tracing_subscriber::prelude::*; use shuttle_service::ResourceBuilder; - runtime.spawn_blocking(move || { - let filter_layer = - shuttle_service::tracing_subscriber::EnvFilter::try_from_default_env() - .or_else(|_| shuttle_service::tracing_subscriber::EnvFilter::try_new("INFO")) - .unwrap(); - - shuttle_service::tracing_subscriber::registry() - .with(filter_layer) - .with(logger) - .init(); - }) - .await - .map_err(|e| { - if e.is_panic() { - let mes = e - .into_panic() - .downcast_ref::<&str>() - .map(|x| x.to_string()) - .unwrap_or_else(|| "panicked setting logger".to_string()); - - shuttle_service::Error::BuildPanic(mes) - } else { - shuttle_service::Error::Custom(shuttle_service::error::CustomError::new(e).context("failed to set logger")) - } - })?; - - let pool = shuttle_shared_db::Postgres::new().size("10Gb").public(false).build(factory, runtime).await.context(format!("failed to provision {}", stringify!(shuttle_shared_db::Postgres)))?; - - runtime.spawn(async { - complex(pool) - .await - .map(|ok| Box::new(ok) as Box) - }) - .await - .map_err(|e| { - if e.is_panic() { - let mes = e - .into_panic() - .downcast_ref::<&str>() - .map(|x| x.to_string()) - .unwrap_or_else(|| "panicked calling main".to_string()); - - shuttle_service::Error::BuildPanic(mes) - } else { - shuttle_service::Error::Custom(shuttle_service::error::CustomError::new(e).context("failed to call main")) - } - })? + let filter_layer = + shuttle_service::tracing_subscriber::EnvFilter::try_from_default_env() + .or_else(|_| shuttle_service::tracing_subscriber::EnvFilter::try_new("INFO")) + .unwrap(); + + shuttle_service::tracing_subscriber::registry() + .with(filter_layer) + .with(logger) + .init(); + + let pool = shuttle_shared_db::Postgres::new().size("10Gb").public(false).build(&mut factory).await.context(format!("failed to provision {}", stringify!(shuttle_shared_db::Postgres)))?; + + complex(pool).await } }; diff --git a/proto/src/lib.rs b/proto/src/lib.rs index a4d51a522..f27281d13 100644 --- a/proto/src/lib.rs +++ b/proto/src/lib.rs @@ -247,27 +247,32 @@ pub mod runtime { port: u16, get_runtime_executable: impl FnOnce() -> PathBuf, ) -> anyhow::Result<(process::Child, runtime_client::RuntimeClient)> { - let runtime_flag = if wasm { "--axum" } else { "--legacy" }; - let (storage_manager_type, storage_manager_path) = match storage_manager_type { StorageManagerType::Artifacts(path) => ("artifacts", path), StorageManagerType::WorkingDir(path) => ("working-dir", path), }; - let runtime_executable = get_runtime_executable(); + let port = &port.to_string(); + let storage_manager_path = &storage_manager_path.display().to_string(); + let runtime_executable_path = get_runtime_executable(); - let runtime = process::Command::new(runtime_executable) - .args([ - runtime_flag, + let args = if wasm { + vec!["--port", port] + } else { + vec![ "--port", - &port.to_string(), + port, "--provisioner-address", provisioner_address, "--storage-manager-type", storage_manager_type, "--storage-manager-path", - &storage_manager_path.display().to_string(), - ]) + storage_manager_path, + ] + }; + + let runtime = process::Command::new(runtime_executable_path) + .args(&args) .spawn() .context("spawning runtime process")?; diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index b9b1ff8df..b8ce5c235 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -10,13 +10,15 @@ publish = false name = "rocket" [[bin]] -name = "next" +name = "shuttle-next" required-features = ["next"] [dependencies] anyhow = { workspace = true } async-trait = { workspace = true } +chrono = { workspace = true } clap ={ version = "4.0.18", features = ["derive"] } +serde_json = { workspace = true } thiserror = { workspace = true } tokio = { version = "1.22.0", features = ["full"] } tokio-stream = "0.1.11" diff --git a/runtime/src/bin/rocket.rs b/runtime/src/bin/rocket.rs index 8da00a54f..9222f709d 100644 --- a/runtime/src/bin/rocket.rs +++ b/runtime/src/bin/rocket.rs @@ -6,6 +6,7 @@ async fn main() { async fn loader( mut factory: shuttle_runtime::ProvisionerFactory, + logger: shuttle_runtime::Logger, ) -> shuttle_service::ShuttleRocket { use shuttle_service::ResourceBuilder; diff --git a/runtime/src/bin/next.rs b/runtime/src/bin/shuttle-next.rs similarity index 100% rename from runtime/src/bin/next.rs rename to runtime/src/bin/shuttle-next.rs diff --git a/runtime/src/legacy/mod.rs b/runtime/src/legacy/mod.rs index a040a8640..9cc3fa4b3 100644 --- a/runtime/src/legacy/mod.rs +++ b/runtime/src/legacy/mod.rs @@ -36,7 +36,7 @@ use tonic::{ use tracing::{error, instrument, trace}; use uuid::Uuid; -use crate::provisioner_factory::ProvisionerFactory; +use crate::{provisioner_factory::ProvisionerFactory, Logger}; use self::args::Args; @@ -100,21 +100,29 @@ where { type Service: Service; - async fn load(self, factory: Fac) -> Result; + async fn load( + self, + factory: Fac, + logger: Logger, + ) -> Result; } #[async_trait] impl Loader for F where - F: FnOnce(Fac) -> O + Send, + F: FnOnce(Fac, Logger) -> O + Send, O: Future> + Send, Fac: Factory + 'static, S: Service, { type Service = S; - async fn load(self, factory: Fac) -> Result { - (self)(factory).await + async fn load( + self, + factory: Fac, + logger: Logger, + ) -> Result { + (self)(factory, logger).await } } @@ -154,9 +162,12 @@ where ); trace!("got factory"); + let logs_tx = self.logs_tx.clone(); + let logger = Logger::new(logs_tx, deployment_id); + let loader = self.loader.lock().unwrap().deref_mut().take().unwrap(); - let service = loader.load(factory).await.unwrap(); + let service = loader.load(factory, logger).await.unwrap(); *self.service.lock().unwrap() = Some(service); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 33babf1c7..6e51ff0f4 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1,9 +1,12 @@ mod legacy; +mod logger; #[cfg(feature = "next")] mod next; mod provisioner_factory; pub use legacy::{start, Legacy}; +pub use logger::Logger; #[cfg(feature = "next")] pub use next::{AxumWasm, NextArgs}; pub use provisioner_factory::ProvisionerFactory; +pub use shuttle_common::storage_manager::StorageManager; diff --git a/service/src/logger.rs b/runtime/src/logger.rs similarity index 100% rename from service/src/logger.rs rename to runtime/src/logger.rs diff --git a/service/Cargo.toml b/service/Cargo.toml index ae3a29eb8..f9943a4d2 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -18,7 +18,6 @@ bincode = { version = "1.3.3", optional = true } # TODO: debug the libgit2-sys conflict with cargo-edit when upgrading cargo to 0.66 cargo = { version = "0.65.0", optional = true } cargo_metadata = "0.15.2" -chrono = { workspace = true } crossbeam-channel = "0.5.6" futures = { version = "0.3.25", features = ["std"] } hyper = { version = "0.14.23", features = ["server", "tcp", "http1"], optional = true } diff --git a/service/src/builder.rs b/service/src/builder.rs index 870284206..3fcd8c67f 100644 --- a/service/src/builder.rs +++ b/service/src/builder.rs @@ -62,13 +62,12 @@ pub async fn build_crate( check_no_panic(&ws)?; let opts = get_compile_options(&config, release_mode, is_next)?; - let compilation = compile(&ws, &opts); + let compilation = compile(&ws, &opts)?; - let path = compilation?.binaries[0].path.clone(); Ok(if is_next { - Runtime::Next(path) + Runtime::Next(compilation.cdylibs[0].path.clone()) } else { - Runtime::Legacy(path) + Runtime::Legacy(compilation.binaries[0].path.clone()) }) } diff --git a/service/src/lib.rs b/service/src/lib.rs index c7a6e189c..de58ad046 100644 --- a/service/src/lib.rs +++ b/service/src/lib.rs @@ -223,9 +223,6 @@ pub use tracing_subscriber; pub mod error; pub use error::Error; -mod logger; -pub use logger::Logger; - pub use shuttle_common::database; #[cfg(feature = "codegen")]