Skip to content

Commit dd85c4e

Browse files
authored
chore: stop HTTP gateway gracefully (#4009)
* chore: stop HTTP gateway gracefully * windows
1 parent 06afa6f commit dd85c4e

File tree

1 file changed

+44
-16
lines changed

1 file changed

+44
-16
lines changed

src/dfx/src/actors/pocketic_proxy.rs

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -284,23 +284,26 @@ fn pocketic_proxy_start_thread(
284284
}
285285
}
286286
};
287-
if let Err(e) = initialize_gateway(
287+
let instance = match initialize_gateway(
288288
format!("http://localhost:{port}").parse().unwrap(),
289289
replica_url.clone(),
290290
domains.clone(),
291291
address,
292292
logger.clone(),
293293
) {
294-
error!(logger, "Failed to initialize HTTP gateway: {e:#}");
295-
let _ = child.kill();
296-
let _ = child.wait();
297-
if receiver.try_recv().is_ok() {
298-
debug!(logger, "Got signal to stop.");
299-
break;
300-
} else {
301-
continue;
294+
Err(e) => {
295+
error!(logger, "Failed to initialize HTTP gateway: {e:#}");
296+
let _ = child.kill();
297+
let _ = child.wait();
298+
if receiver.try_recv().is_ok() {
299+
debug!(logger, "Got signal to stop.");
300+
break;
301+
} else {
302+
continue;
303+
}
302304
}
303-
}
305+
Ok(i) => i,
306+
};
304307
info!(logger, "Replica API running on {address}");
305308

306309
// Send PocketIcProxyReadySignal to PocketIcProxy.
@@ -314,6 +317,9 @@ fn pocketic_proxy_start_thread(
314317
logger,
315318
"Got signal to stop. Killing pocket-ic gateway process..."
316319
);
320+
if let Err(e) = shutdown_pocketic_proxy(port, instance, logger.clone()) {
321+
error!(logger, "Error shutting down PocketIC gracefully: {e}");
322+
}
317323
let _ = child.kill();
318324
let _ = child.wait();
319325
break;
@@ -349,7 +355,7 @@ async fn initialize_gateway(
349355
domains: Option<Vec<String>>,
350356
addr: SocketAddr,
351357
logger: Logger,
352-
) -> DfxResult {
358+
) -> DfxResult<usize> {
353359
use pocket_ic::common::rest::{
354360
CreateHttpGatewayResponse, HttpGatewayBackend, HttpGatewayConfig,
355361
};
@@ -369,11 +375,12 @@ async fn initialize_gateway(
369375
.await?
370376
.error_for_status()?;
371377
let resp = resp.json::<CreateHttpGatewayResponse>().await?;
372-
if let CreateHttpGatewayResponse::Error { message } = resp {
373-
bail!("Gateway init error: {message}")
374-
}
378+
let instance = match resp {
379+
CreateHttpGatewayResponse::Created(info) => info.instance_id,
380+
CreateHttpGatewayResponse::Error { message } => bail!("Gateway init error: {message}"),
381+
};
375382
info!(logger, "Initialized HTTP gateway.");
376-
Ok(())
383+
Ok(instance)
377384
}
378385

379386
#[cfg(not(unix))]
@@ -383,6 +390,27 @@ fn initialize_gateway(
383390
_: Option<Vec<String>>,
384391
_: SocketAddr,
385392
_: Logger,
386-
) -> DfxResult {
393+
) -> DfxResult<usize> {
387394
bail!("PocketIC gateway not supported on this platform")
388395
}
396+
397+
#[cfg(unix)]
398+
#[tokio::main(flavor = "current_thread")]
399+
async fn shutdown_pocketic_proxy(port: u16, instance: usize, logger: Logger) -> DfxResult {
400+
use reqwest::Client;
401+
let shutdown_client = Client::new();
402+
debug!(logger, "Sending shutdown request to HTTP gateway");
403+
shutdown_client
404+
.post(format!(
405+
"http://localhost:{port}/http_gateway/{instance}/stop"
406+
))
407+
.send()
408+
.await?
409+
.error_for_status()?;
410+
Ok(())
411+
}
412+
413+
#[cfg(not(unix))]
414+
fn shutdown_pocketic_proxy(_: u16, _: usize, _: Logger) -> DfxResult {
415+
bail!("PocketIC not supported on this platform")
416+
}

0 commit comments

Comments
 (0)