Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
Summary I'm refactoring a Rust-based service/daemon to move away from gRPC and use a Rocket-based API instead. I'm also using the daemonize crate to turn the foreground process into a background p...
#4: Post edited
- # Summary
- I'm refactoring a Rust-based service/daemon to move away from gRPC and use a [Rocket](https://rocket.rs)-based API instead. I'm also using the [`daemonize`](https://crates.io/crates/daemonize) crate to turn the foreground process into a background process.
- The problem I've run into is that when I get the `rocket`-based service to successfully daemonize itself (i.e. `daemon.start()` returns `Ok()` result), it *never* receives the HTTP requests sent to it. In other words, no HTTP requests are ever logged as having been received by Rocket while the client side (i.e. `curl -X GET ...` in this case) keeps waiting for a response until it times out.
- If I run the Rocket-based service in the foreground, i.e. without `daemonize`, then it works as expected. Also, my usage of `daemonize` before refactoring the service to use Rocket was showing correct behavior.
- # Questions
- Given the constraints (see later):
- 1. How can I get Rocket to work properly when turned into a background process with daemonize?
- 2. Is there a better approach than using daemonize to turn a Rocket app into a background service?
- 3. Any suggestions on gathering more data to troubleshoot this issue (e.g. determine if Rocket is failing to receive requests or refusing to process them - i.e. hung)? (I'll be running a few tests later with `tcpdump` to see what I can find out.)
- The only thing that stands out here is my attempt to mix Rocket with Daemonize. The Rocket docs don't seem to have info on how to turn run it as a background service.
- ### Constraints
- 1. Launching the service as `./service &` will not be possible in production;
- 2. This is on an embedded device running Yocto and `systemd` is *not* available, so I cannot replace my usage of `daemonize` by a service unit
- Please note that the above are not my decisions to make, are beyond my control, and are not likely to change. (I'm still looking into it, but, for the sake of this question, we should *assume* that it won't be possible.)
- # Code Ref
- Here's the code using `daemonize` for reference:
- ```rust
- fn launch_background(figment: Figment, config: Config) -> Rocket<Build> {
- let daemon = Daemonize::new()
- .pid_file(config.service.files.pid_file.clone())
- .chown_pid_file(true)
- .working_directory(config.service.context.working_dir.clone())
- .user(config.service.context.user.as_str())
- .group(config.service.context.group.as_str())
- .umask(config.service.context.umask)
- .stderr(File::create(config.service.files.log_file.clone()).unwrap());
- match daemon.start() {
- Ok(_) => launch_foreground(figment, config),
- Err(e) => ...
- }
- }
- ```
- Here's the code of how Rocket is being launched
- ```rust
- fn launch_foreground(figment: Figment, config: Config) -> Rocket<Build> {
- rocket::custom(figment)
- .manage(...)
- .manage(...)
- .mount(...)
- .mount(...)
- }
- ```
- This is what Rocket shows when launched, regardless of whether it's daemonized or not (shortened for brevity):
- ```bash
- [2022-07-09T00:46:00Z INFO rocket::launch] 🔧 Configured for default.
- [2022-07-09T00:46:00Z INFO rocket::launch_] address: 127.0.0.1
- [2022-07-09T00:46:00Z INFO rocket::launch_] port: 50051
- <snip>
- [2022-07-09T00:46:00Z INFO rocket::launch] 📬 Routes:
- [2022-07-09T00:46:00Z INFO rocket::launch_] (get_config) GET ...
- [2022-07-09T00:46:00Z INFO rocket::launch_] (get_downcast_info) GET ...
- [2022-07-09T00:46:00Z INFO rocket::launch_] (get_downcast_state) GET ...
- <snip>
- [2022-07-09T00:46:00Z INFO rocket::launch] 🚀 Rocket has launched from http://127.0.0.1:50051
- ```
From the above, there're no obvious issues. There're no warnings or errors either. However, when sending HTTP requests to the mounted endpoints, nothing is ever logged by Rocket, so it's either *not receiving* any requests or it's hung in some way and it's *not processing* anything. I think the latter is more likely, but I'm not sure why that would happen either.
- # Summary
- I'm refactoring a Rust-based service/daemon to move away from gRPC and use a [Rocket](https://rocket.rs)-based API instead. I'm also using the [`daemonize`](https://crates.io/crates/daemonize) crate to turn the foreground process into a background process.
- The problem I've run into is that when I get the `rocket`-based service to successfully daemonize itself (i.e. `daemon.start()` returns `Ok()` result), it *never* receives the HTTP requests sent to it. In other words, no HTTP requests are ever logged as having been received by Rocket while the client side (i.e. `curl -X GET ...` in this case) keeps waiting for a response until it times out.
- If I run the Rocket-based service in the foreground, i.e. without `daemonize`, then it works as expected. Also, my usage of `daemonize` before refactoring the service to use Rocket was showing correct behavior.
- # Questions
- Given the constraints (see later):
- 1. How can I get Rocket to work properly when turned into a background process with daemonize?
- 2. Is there a better approach than using daemonize to turn a Rocket app into a background service?
- 3. Any suggestions on gathering more data to troubleshoot this issue (e.g. determine if Rocket is failing to receive requests or refusing to process them - i.e. hung)? (I'll be running a few tests later with `tcpdump` to see what I can find out.)
- The only thing that stands out here is my attempt to mix Rocket with Daemonize. The Rocket docs don't seem to have info on how to turn run it as a background service.
- ### Constraints
- 1. Launching the service as `./service &` will not be possible in production;
- 2. This is on an embedded device running Yocto and `systemd` is *not* available, so I cannot replace my usage of `daemonize` by a service unit
- Please note that the above are not my decisions to make, are beyond my control, and are not likely to change. (I'm still looking into it, but, for the sake of this question, we should *assume* that it won't be possible.)
- # Code Ref
- Here's the code using `daemonize` for reference:
- ```rust
- fn launch_background(figment: Figment, config: Config) -> Rocket<Build> {
- let daemon = Daemonize::new()
- .pid_file(config.service.files.pid_file.clone())
- .chown_pid_file(true)
- .working_directory(config.service.context.working_dir.clone())
- .user(config.service.context.user.as_str())
- .group(config.service.context.group.as_str())
- .umask(config.service.context.umask)
- .stderr(File::create(config.service.files.log_file.clone()).unwrap());
- match daemon.start() {
- Ok(_) => launch_foreground(figment, config),
- Err(e) => ...
- }
- }
- ```
- Here's the code of how Rocket is being launched
- ```rust
- fn launch_foreground(figment: Figment, config: Config) -> Rocket<Build> {
- rocket::custom(figment)
- .manage(...)
- .manage(...)
- .mount(...)
- .mount(...)
- }
- ```
- This is what Rocket shows when launched, regardless of whether it's daemonized or not (shortened for brevity):
- ```bash
- [2022-07-09T00:46:00Z INFO rocket::launch] 🔧 Configured for default.
- [2022-07-09T00:46:00Z INFO rocket::launch_] address: 127.0.0.1
- [2022-07-09T00:46:00Z INFO rocket::launch_] port: 50051
- <snip>
- [2022-07-09T00:46:00Z INFO rocket::launch] 📬 Routes:
- [2022-07-09T00:46:00Z INFO rocket::launch_] (get_config) GET ...
- [2022-07-09T00:46:00Z INFO rocket::launch_] (get_downcast_info) GET ...
- [2022-07-09T00:46:00Z INFO rocket::launch_] (get_downcast_state) GET ...
- <snip>
- [2022-07-09T00:46:00Z INFO rocket::launch] 🚀 Rocket has launched from http://127.0.0.1:50051
- ```
- From the above, there're no obvious issues. There're no warnings or errors either. However, when sending HTTP requests to the mounted endpoints, nothing is ever logged by Rocket, so it's either *not receiving* any requests or it's hung in some way and it's *not processing* anything. I think the latter is more likely, but I'm not sure why that would happen either.
- # Update
- This is a packet capture using Wireshark when the Rocket app is running as a background service/daemon. Notice that the 5th packet (#153) is a transport layer TCP `ACK` packet from the Rocket app side following the client's application layer HTTP `GET` request packet (#152), but the app layer on the service end (i.e. Rocket itself) did not respond. After a while, Keep-Alive packets start to show up until the connection is, eventually, terminated.
- ![Rocket/cURL Network Traffic](https://software.codidact.com/uploads/HUmwxjyQEdgdQU1oy73U2Qi1)
#2: Post edited
Rocket fails to receive or process requests when Daemonized
- How to correctly daemonize a Rocket-based app?
#1: Initial revision
Rocket fails to receive or process requests when Daemonized
# Summary I'm refactoring a Rust-based service/daemon to move away from gRPC and use a [Rocket](https://rocket.rs)-based API instead. I'm also using the [`daemonize`](https://crates.io/crates/daemonize) crate to turn the foreground process into a background process. The problem I've run into is that when I get the `rocket`-based service to successfully daemonize itself (i.e. `daemon.start()` returns `Ok()` result), it *never* receives the HTTP requests sent to it. In other words, no HTTP requests are ever logged as having been received by Rocket while the client side (i.e. `curl -X GET ...` in this case) keeps waiting for a response until it times out. If I run the Rocket-based service in the foreground, i.e. without `daemonize`, then it works as expected. Also, my usage of `daemonize` before refactoring the service to use Rocket was showing correct behavior. # Questions Given the constraints (see later): 1. How can I get Rocket to work properly when turned into a background process with daemonize? 2. Is there a better approach than using daemonize to turn a Rocket app into a background service? 3. Any suggestions on gathering more data to troubleshoot this issue (e.g. determine if Rocket is failing to receive requests or refusing to process them - i.e. hung)? (I'll be running a few tests later with `tcpdump` to see what I can find out.) The only thing that stands out here is my attempt to mix Rocket with Daemonize. The Rocket docs don't seem to have info on how to turn run it as a background service. ### Constraints 1. Launching the service as `./service &` will not be possible in production; 2. This is on an embedded device running Yocto and `systemd` is *not* available, so I cannot replace my usage of `daemonize` by a service unit Please note that the above are not my decisions to make, are beyond my control, and are not likely to change. (I'm still looking into it, but, for the sake of this question, we should *assume* that it won't be possible.) # Code Ref Here's the code using `daemonize` for reference: ```rust fn launch_background(figment: Figment, config: Config) -> Rocket<Build> { let daemon = Daemonize::new() .pid_file(config.service.files.pid_file.clone()) .chown_pid_file(true) .working_directory(config.service.context.working_dir.clone()) .user(config.service.context.user.as_str()) .group(config.service.context.group.as_str()) .umask(config.service.context.umask) .stderr(File::create(config.service.files.log_file.clone()).unwrap()); match daemon.start() { Ok(_) => launch_foreground(figment, config), Err(e) => ... } } ``` Here's the code of how Rocket is being launched ```rust fn launch_foreground(figment: Figment, config: Config) -> Rocket<Build> { rocket::custom(figment) .manage(...) .manage(...) .mount(...) .mount(...) } ``` This is what Rocket shows when launched, regardless of whether it's daemonized or not (shortened for brevity): ```bash [2022-07-09T00:46:00Z INFO rocket::launch] 🔧 Configured for default. [2022-07-09T00:46:00Z INFO rocket::launch_] address: 127.0.0.1 [2022-07-09T00:46:00Z INFO rocket::launch_] port: 50051 <snip> [2022-07-09T00:46:00Z INFO rocket::launch] 📬 Routes: [2022-07-09T00:46:00Z INFO rocket::launch_] (get_config) GET ... [2022-07-09T00:46:00Z INFO rocket::launch_] (get_downcast_info) GET ... [2022-07-09T00:46:00Z INFO rocket::launch_] (get_downcast_state) GET ... <snip> [2022-07-09T00:46:00Z INFO rocket::launch] 🚀 Rocket has launched from http://127.0.0.1:50051 ``` From the above, there're no obvious issues. There're no warnings or errors either. However, when sending HTTP requests to the mounted endpoints, nothing is ever logged by Rocket, so it's either *not receiving* any requests or it's hung in some way and it's *not processing* anything. I think the latter is more likely, but I'm not sure why that would happen either.