Skip to content

Commit e5171ce

Browse files
committed
Auto merge of #3417 - jtgeibel:downloads-counter, r=pietroalbini
Boot nginx from the backend app to fix graceful shutdown in production In production we aren't gracefully shutting down as expected. nginx does a quick shutdown when receiving a `SIGTERM` and once it exits, it appears that our process is aborted. Instead of spawning the backend from the shell script, the backend process is now responsible for spawning the shell script. This allows the backend to finish its shutdown work even if the script has already exited. `cat` is passed to the nginx buildpack script as our "server", which will block on `STDIN` so that `nginx` will run until receiving `SIGTERM`. r? `@pietroalbini`
2 parents 7e55937 + 0061c5f commit e5171ce

File tree

4 files changed

+16
-9
lines changed

4 files changed

+16
-9
lines changed

Procfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
release: bin/diesel migration run
2-
web: ./script/start-web.sh
2+
web: ./target/release/server
33
background_worker: ./target/release/background-worker

script/start-web.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
#! /bin/bash
22
set -ue
33

4+
# Since this script is launched from our app, we tell the nginx
5+
# buildpack (`bin/start-nginx`) that `cat` is our server.
6+
47
if [[ -z "${USE_FASTBOOT-}" ]]; then
58
unset USE_FASTBOOT
6-
bin/start-nginx ./target/release/server
9+
bin/start-nginx cat
710
else
811
export USE_FASTBOOT
912
node --optimize_for_size --max_old_space_size=200 fastboot.js &
10-
bin/start-nginx ./target/release/server &
13+
bin/start-nginx cat &
1114
wait -n
1215
fi

src/bin/server.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use cargo_registry::{boot, App, Env};
55
use std::{
66
borrow::Cow,
77
fs::File,
8+
process::Command,
89
sync::{mpsc::channel, Arc, Mutex},
9-
thread,
1010
time::Duration,
1111
};
1212

@@ -139,9 +139,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
139139

140140
println!("listening on port {}", port);
141141

142-
// Give tokio a chance to spawn the first worker thread
143-
thread::sleep(Duration::from_millis(10));
144-
145142
// Creating this file tells heroku to tell nginx that the application is ready
146143
// to receive traffic.
147144
if heroku {
@@ -152,6 +149,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
152149
};
153150
println!("Writing to {}", path);
154151
File::create(path).unwrap();
152+
153+
// Launch nginx via the Heroku nginx buildpack
154+
// `wait()` is never called on the child process, but it should be okay to leave a zombie
155+
// process around on shutdown when Heroku is tearing down the entire container anyway.
156+
Command::new("./script/start-web.sh")
157+
.spawn()
158+
.expect("Couldn't spawn nginx");
155159
}
156160

157161
// Block the main thread until the server has shutdown

src/downloads_counter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl DownloadsCounter {
8080
}
8181

8282
println!(
83-
"download_counter all_shards counted_versions={} counted_downloads={} pending_downloads={}",
83+
"downloads_counter all_shards counted_versions={} counted_downloads={} pending_downloads={}",
8484
counted_versions,
8585
counted_downloads,
8686
pending_downloads,
@@ -101,7 +101,7 @@ impl DownloadsCounter {
101101

102102
let stats = self.persist_shard(&conn, shard)?;
103103
println!(
104-
"download_counter shard={} counted_versions={} counted_downloads={} pending_downloads={}",
104+
"downloads_counter shard={} counted_versions={} counted_downloads={} pending_downloads={}",
105105
idx,
106106
stats.counted_versions,
107107
stats.counted_downloads,

0 commit comments

Comments
 (0)