Skip to content

Commit 2a0d255

Browse files
committed
fix sigterm issue with translator sv2
1 parent e8d76d6 commit 2a0d255

File tree

1 file changed

+60
-53
lines changed
  • roles/translator/src/lib

1 file changed

+60
-53
lines changed

roles/translator/src/lib/mod.rs

+60-53
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::{
1010
};
1111

1212
use tokio::{
13-
sync::broadcast,
13+
sync::{broadcast, Notify as notification},
1414
task::{self, AbortHandle},
1515
};
1616
use tracing::{debug, error, info, warn};
@@ -32,6 +32,7 @@ pub mod utils;
3232
pub struct TranslatorSv2 {
3333
config: ProxyConfig,
3434
reconnect_wait_time: u64,
35+
shutdown: Arc<notification>,
3536
}
3637

3738
impl TranslatorSv2 {
@@ -41,6 +42,7 @@ impl TranslatorSv2 {
4142
Self {
4243
config,
4344
reconnect_wait_time: wait_time,
45+
shutdown: Arc::new(notification::new()),
4446
}
4547
}
4648

@@ -58,7 +60,8 @@ impl TranslatorSv2 {
5860
let task_collector: Arc<Mutex<Vec<(AbortHandle, String)>>> =
5961
Arc::new(Mutex::new(Vec::new()));
6062

61-
self.internal_start(
63+
Self::internal_start(
64+
self.config.clone(),
6265
tx_sv1_notify.clone(),
6366
target.clone(),
6467
tx_status.clone(),
@@ -72,74 +75,78 @@ impl TranslatorSv2 {
7275
debug!("Starting up status listener");
7376
let wait_time = self.reconnect_wait_time;
7477
// Check all tasks if is_finished() is true, if so exit
75-
loop {
76-
let task_status = tokio::select! {
77-
task_status = rx_status.recv().fuse() => task_status,
78-
interrupt_signal = tokio::signal::ctrl_c().fuse() => {
79-
match interrupt_signal {
80-
Ok(()) => {
81-
info!("Interrupt received");
82-
},
83-
Err(err) => {
84-
error!("Unable to listen for interrupt signal: {}", err);
85-
// we also shut down in case of error
86-
},
87-
}
88-
break;
89-
}
90-
};
91-
let task_status: Status = task_status.unwrap();
9278

93-
match task_status.state {
94-
// Should only be sent by the downstream listener
95-
State::DownstreamShutdown(err) => {
96-
error!("SHUTDOWN from: {}", err);
97-
break;
98-
}
99-
State::BridgeShutdown(err) => {
100-
error!("SHUTDOWN from: {}", err);
101-
break;
79+
tokio::spawn({
80+
let shutdown_signal = self.shutdown.clone();
81+
async move {
82+
if tokio::signal::ctrl_c().await.is_ok() {
83+
info!("Interrupt received");
84+
shutdown_signal.notify_one();
10285
}
103-
State::UpstreamShutdown(err) => {
104-
error!("SHUTDOWN from: {}", err);
105-
break;
106-
}
107-
State::UpstreamTryReconnect(err) => {
108-
error!("SHUTDOWN from: {}", err);
86+
}
87+
});
10988

110-
// wait a random amount of time between 0 and 3000ms
111-
// if all the downstreams try to reconnect at the same time, the upstream may
112-
// fail
113-
tokio::time::sleep(std::time::Duration::from_millis(wait_time)).await;
89+
loop {
90+
tokio::select! {
91+
task_status = rx_status.recv().fuse() => {
92+
if let Ok(task_status_) = task_status {
93+
match task_status_.state {
94+
State::DownstreamShutdown(err) | State::BridgeShutdown(err) | State::UpstreamShutdown(err) => {
95+
error!("SHUTDOWN from: {}", err);
96+
self.shutdown.notify_one();
97+
}
98+
State::UpstreamTryReconnect(err) => {
99+
error!("SHUTDOWN from: {}", err);
100+
let task_collector1 = task_collector_.clone();
101+
let tx_sv1_notify1 = tx_sv1_notify.clone();
102+
let target = target.clone();
103+
let tx_status = tx_status.clone();
104+
let proxy_config = self.config.clone();
105+
tokio::spawn (async move {
106+
// wait a random amount of time between 0 and 3000ms
107+
// if all the downstreams try to reconnect at the same time, the upstream may
108+
// fail
109+
tokio::time::sleep(std::time::Duration::from_millis(wait_time)).await;
114110

115-
// kill al the tasks
116-
let task_collector_aborting = task_collector_.clone();
117-
kill_tasks(task_collector_aborting.clone());
111+
// kill al the tasks
112+
let task_collector_aborting = task_collector1.clone();
113+
kill_tasks(task_collector_aborting.clone());
118114

119-
warn!("Trying reconnecting to upstream");
120-
self.internal_start(
121-
tx_sv1_notify.clone(),
122-
target.clone(),
123-
tx_status.clone(),
124-
task_collector_.clone(),
125-
)
126-
.await;
115+
warn!("Trying reconnecting to upstream");
116+
Self::internal_start(
117+
proxy_config,
118+
tx_sv1_notify1,
119+
target.clone(),
120+
tx_status.clone(),
121+
task_collector1,
122+
)
123+
.await;
124+
});
125+
}
126+
State::Healthy(msg) => {
127+
info!("HEALTHY message: {}", msg);
128+
self.shutdown.notify_one();
129+
}
130+
}
131+
} else {
132+
break; // Channel closed
133+
}
127134
}
128-
State::Healthy(msg) => {
129-
info!("HEALTHY message: {}", msg);
135+
_ = self.shutdown.notified() => {
136+
info!("Shutting down gracefully...");
137+
break;
130138
}
131139
}
132140
}
133141
}
134142

135143
async fn internal_start(
136-
&self,
144+
proxy_config: ProxyConfig,
137145
tx_sv1_notify: broadcast::Sender<server_to_client::Notify<'static>>,
138146
target: Arc<Mutex<Vec<u8>>>,
139147
tx_status: async_channel::Sender<Status<'static>>,
140148
task_collector: Arc<Mutex<Vec<(AbortHandle, String)>>>,
141149
) {
142-
let proxy_config = self.config.clone();
143150
// Sender/Receiver to send a SV2 `SubmitSharesExtended` from the `Bridge` to the `Upstream`
144151
// (Sender<SubmitSharesExtended<'static>>, Receiver<SubmitSharesExtended<'static>>)
145152
let (tx_sv2_submit_shares_ext, rx_sv2_submit_shares_ext) = bounded(10);

0 commit comments

Comments
 (0)