https://linen.dev logo
Local run successful, Deploy successful but hangs ...
# help
e
Hello, I'm trying to deploy my realworld project in shuttle. Locally with
cargo shuttle run
works well. The deploy works fine, no errors. But when I try to access my project, it hangs forever. This is my project source: https://github.com/Bechma/realworld-actix-fullstack and this is my page: https://realworld-fullstack.shuttleapp.rs/ Making a request with:
curl -vvv https://realworld-fullstack.shuttleapp.rs
Copy code
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=*.shuttleapp.rs
*  start date: Nov 22 08:22:43 2022 GMT
*  expire date: Feb 20 08:22:42 2023 GMT
*  subjectAltName: host "realworld-fullstack.shuttleapp.rs" matched cert's "*.shuttleapp.rs"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET / HTTP/1.1
> Host: realworld-fullstack.shuttleapp.rs
> User-Agent: curl/7.81.0
> Accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
And here hangs... In the logs, I see sqlx queries, debug globset from Tera but nothing from actix_web of successful request
k
Hmm, this might be because you're using dotenv, could you try replacing it with shuttle-secrets?
Oh, you're not using that in the shuttle function, hmm..
Ah I see, for a static file directory like templates you need to use
e
Adding
#[shuttle_static_folder::StaticFolder(folder = "templates")] static_folder: std::path::PathBuf,
doesn't solve the issue, I still see :
Copy code
2022-12-26T14:17:17.833563037Z DEBUG globset: glob converted to regex: Glob { glob: "templates/**/*", re: "(?-u)^templates(?:/|/.*/)[^/]*$", opts: GlobOptions { case_insensitive: false, literal_separator: true, backslash_escape: true }, tokens: Tokens([Literal('t'), Literal('e'), Literal('m'), Literal('p'), Literal('l'), Literal('a'), Literal('t'), Literal('e'), Literal('s'), RecursiveZeroOrMore, ZeroOrMore]) }
2022-12-26T14:17:17.833575979Z DEBUG globset: built glob set; 0 literals, 0 basenames, 0 extensions, 0 prefixes, 0 suffixes, 0 required extensions, 1 regexes
So nothing changed(this is the expected log messages anyway). BTW: the link you provided have a link pointing to https://github.com/shuttle-hq/examples/tree/main/axum/websocket instead of https://github.com/shuttle-hq/examples/tree/main/axum/static-files
okay, after some investigation, I manage to make it work, I had to tweak my TEMPLATES variable a bit. The static folder is called differently in shuttle, that's something that I wasn't aware of.
https://realworld-fullstack.shuttleapp.rs/ now it's working, thanks a lot for the support and also the great project 😄
k
Nice! 🥳
s
Hey @enough-exabyte-92081, glad you got it working. Mind explaining a bit more what the issue and fix was? We would ideally like this experience to be as painless as possible
e
Sure, so the situation was the following:
Copy code
rust
lazy_static! {
    static ref TEMPLATES: Tera = {
        let mut tera = match Tera::new("templates/**/*") {
            Ok(t) => t,
            Err(e) => {
                println!("Template parsing error(s): {}", e);
                ::std::process::exit(1);
            }
        };
        tera.autoescape_on(vec!["j2"]);
        tera
    };
}
I had something like this in my templates module. This is incompatible with the shuttle initialization, as the parse/loading of templates is done at runtime(not static). So my tweak was:
Copy code
rust
lazy_static::lazy_static! {
    pub static ref TEMPLATES: once_cell::sync::OnceCell<tera::Tera> = once_cell::sync::OnceCell::new();
}
So I had to declare the static reference as
OnceCell
. This way, I can initialize it during main() for local development or in lib during shuttle startup. What I'm not very happy is with the initialization in the tests, as it doesn't behave the way I want... Maybe I'm doing something wrong but at least it loads the templates and got the result expected.
The changes in the code are the following: Before:
TEMPLATES.render(template, context)
After:
TEMPLATES.get().unwrap().render(template, context)
This unwrap is very ugly, but it will work for sure, as the initialization is done before creating the application anyways
s
I see. If you are now using
OnceCell
, then you should be able to drop the
lazy_static
, right?
Also, why not store the templates as an app state? https://actix.rs/docs/application#state
e
I followed the recommended approach in Tera docs, this is why I put it like this. I also tried to reduce the
app_state
because in other project I had huge problems with a memory leak(similar to this issue https://github.com/actix/actix-web/issues/1780 ), and when I dropped the
app_state
from my code, the leak was gone... I'll try to retest it in the future, but I was afraid this time. You are right, I don't need
lazy_static
anymore 😮