shuttle icon indicating copy to clipboard operation
shuttle copied to clipboard

[Bug]: Leptos SSR feature doesn't work nicely with shuttle

Open joshua-mo-143 opened this issue 2 years ago • 7 comments
trafficstars

What happened?

repo link https://github.com/joshua-mo-143/lta original thread link https://discord.com/channels/803236282088161321/1118239204850290729

using cargo shuttle 0.18.0 with dependencies at 0.18.0

when using cargo run --no-default-features --features=ssr shuttle run (or something similar) it just says the future can't be sent safely between threads:

error: future cannot be sent between threads safely
  --> src/main.rs:2:1
   |
2  | #[shuttle_runtime::main]
   | ^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `loader` is not `Send`
   |
   = help: within `LocalSet`, the trait `Sync` is not implemented for `*const ()`
note: required by a bound in `start`
  --> /home/joshuamo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/shuttle-runtime-0.18.0/src/alpha/mod.rs:52:33
   |
52 | pub async fn start(loader: impl Loader<ProvisionerFactory> + Send + 'static) {
   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `start`
   = note: this error originates in the attribute macro `shuttle_runtime::main` (in Nightly builds, run with -Z macro-backtrace for more info)

using cargo shuttle run returns this:

    Building /home/joshuamo/lta
   Compiling leptos-tailwind v0.1.0 (/home/joshuamo/lta)
    Finished dev [unoptimized + debuginfo] target(s) in 4.02s
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: connecting runtime client

Caused by:
    0: transport error
    1: error trying to connect: tcp connect error: Connection refused (os error 111)
    2: tcp connect error: Connection refused (os error 111)
    3: Connection refused (os error 111)', /home/circleci/project/cargo-shuttle/src/lib.rs:772:51

It looks like the codegen is being ran on top of the Leptos feature restriction meaning that the shuttle runtime macro runs into problems when trying to use the SSR feature.

Version

v0.18.0

Which operating system(s) are you seeing the problem on?

Linux

Which CPU architectures are you seeing the problem on?

x86_64

Relevant log output

error: future cannot be sent between threads safely
  --> src/main.rs:2:1
   |
2  | #[shuttle_runtime::main]
   | ^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `loader` is not `Send`
   |
   = help: within `LocalSet`, the trait `Sync` is not implemented for `*const ()`
note: required by a bound in `start`
  --> /home/joshuamo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/shuttle-runtime-0.18.0/src/alpha/mod.rs:52:33
   |
52 | pub async fn start(loader: impl Loader<ProvisionerFactory> + Send + 'static) {
   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `start`
   = note: this error originates in the attribute macro `shuttle_runtime::main` (in Nightly builds, run with -Z macro-backtrace for more info)

Duplicate declaration

  • [X] I have searched the issues and there are none like this.

joshua-mo-143 avatar Jun 13 '23 19:06 joshua-mo-143

I just wanna mention a fix that tried to apply:

// main.rs
cfg_if::cfg_if! {
  if #[cfg(feature = "ssr")] {
    #[shuttle_runtime::main]
    async fn axum() -> shuttle_axum::ShuttleAxum {
        use axum::{extract::Extension, routing::post, Router};
        use leptos::*;
        use leptos_axum::{generate_route_list, LeptosRoutes};
        use leptos_tailwind::app::*;
        use leptos_tailwind::fileserv::file_and_error_handler;
        use std::sync::Arc;
    
            // Setting get_configuration(None) means we'll be using cargo-leptos's env values
        // For deployment these variables are:
        // <https://github.com/leptos-rs/start-axum#executing-a-server-on-a-remote-machine-without-the-toolchain>
        // Alternately a file can be specified such as Some("Cargo.toml")
        // The file would need to be included with the executable when moved to deployment
        let conf = get_configuration(Some("Cargo.toml")).await.unwrap();
        let leptos_options = conf.leptos_options;
        let routes = generate_route_list(|cx| view! { cx, <App/> }).await;
    
        // build our application with a route
        let app = Router::new()
            .route("/api/*fn_name", post(leptos_axum::handle_server_fns))
            .leptos_routes(leptos_options.clone(), routes, |cx| view! { cx, <App/> })
            .fallback(file_and_error_handler)
            .layer(Extension(Arc::new(leptos_options)));
    
        Ok(app.into())
    }
  } else {
      pub fn main() {
          // no client-side main function
          // unless we want this to work with e.g., Trunk for a purely client-side app
          // see lib.rs for hydration function instead
      }
  }
}

This code generation from the SSR should not be compiled in the frontend when the frontend is built with: LEPTOS_OUTPUT_NAME=tailwind LEPTOS_SITE_ROOT=site LEPTOS_SITE_PKG_DIR=pkg LEPTOS_SITE_ADDR=127.0.0.1:8000 LEPTOS_RELOAD_PORT=3001 LEPTOS_LIB_DIR=. LEPTOS_BIN_DIR=. cargo build --package=leptos-tailwind --lib --target-dir=target/front --target=wasm32-unknown-unknown --no-default-features --features=hydrate

The error outputed is the one that joshua shared in the OP(from the SSR feature branch while compiling the hydrate feature)

Bechma avatar Jun 14 '23 17:06 Bechma

I'd love to use shuttle for an SSR'd Leptos site, watching this issue for progress :+1:

DougAnderson444 avatar Oct 30 '23 17:10 DougAnderson444

Hello @joshua-mo-143 & @ivancernja et al,

I'm working on updating the Leptos book right now - I was just wondering if there's been any progress on resolving the Leptos SSR issue?

It would be really great to include Shuttle in the Leptos book as a realistic deployment option for full Leptos apps - I know several people in the Leptos community have been asking & wondering about this..!

Thanks!

Daniel

diversable avatar Dec 13 '23 04:12 diversable

Hey everyone, apologies for the delayed answer.

It looks like someone from Discord actually got Leptos working. You can find their notes as below, but be warned it's quite hacky:


I made a repo for the project at https://github.com/x04/shuttle-leptos

There are only really 2 files of interest: https://github.com/x04/shuttle-leptos/blob/main/build.rs https://github.com/x04/shuttle-leptos/blob/main/src/main.rs

hacky stuff:

  • uses cargo leptos as a lib in build.rs
    • for the build script i opted to just use the cargo leptos cli as a library since that means it shares most of it's logic 1:1 with cargo leptos when building, mainly just nice to make sure leptos metadata in Cargo.toml is used. without using the leptos cli there would be a lot of very similar functionality that would have to be recreated, but that also means that if there's an update then the build logic would need an update. the only thing that is left out is the actual build of the server, which is left out because we are building the server when build.rs is ran.
    • this does mean that i had to do a somewhat weird fix to multiple calls to build.rs in the form of setting and checking the BUILD_LOCK_ENV var since the cargo leptos cli will make calls to cargo build again (thinking back on this i could've probably just checked for the ssr feature, but same result)
  • fixing wasm file name at runtime
    • because i am doing all of this build logic in build.rs i have no way of setting the LEPTOS_OUTPUT_NAME env during build time to prevent the check in the first file linked below from being triggered so the logic shown in the last link is necessary to add that _bg suffix to the file name since we know leptos will add it
    • https://github.com/leptos-rs/leptos/blob/8a90f979597ee47233740b3670ea76583d7253ac/integrations/utils/src/lib.rs#L89-L95
    • https://github.com/leptos-rs/leptos/issues/1337
    • https://github.com/x04/shuttle-leptos/blob/main/src/main.rs#L23-L30

This issue is aimed to remain open until we can officially support Leptos through the new builder service that is being created. However, we are not exactly sure as to what the ETA is.

joshua-mo-143 avatar Dec 13 '23 10:12 joshua-mo-143

Hello, thanks for the notes on this. Is there any way one could contribute to the builder service (or other changes required) i.e. is there a branch available or design notes?

atcol avatar Jan 03 '24 09:01 atcol

@atcol ~~The builder directory currently holds an early version of the builder service. You can look at how it and nbuild works, and investigate ideas for how to support something like cargo leptos build. We have not yet settled on a design for this.~~ Edit: Future update to the builder will support Leptos SSR.

jonaro00 avatar Jan 03 '24 09:01 jonaro00