Skip to content

Commit 4e91521

Browse files
committed
new wait_for_process_ready fn
1 parent edb7787 commit 4e91521

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

src/hyperapp.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,88 @@ pub fn pretty_print_send_error(error: &SendError) {
594594
);
595595
}
596596

597+
/// Classification for readiness polling of another process.
598+
#[derive(Debug, PartialEq, Eq)]
599+
pub enum WaitClassification {
600+
/// The target responded but indicated it is still starting up.
601+
Starting,
602+
/// The target is ready (or responded with a payload we consider ready).
603+
Ready,
604+
/// The target responded with an unknown payload.
605+
Unknown,
606+
}
607+
608+
/// Poll a target process until it reports ready.
609+
///
610+
/// - `target`: process address to poll (e.g., hypermap-cacher).
611+
/// - `request_body`: request payload to send each attempt.
612+
/// - `timeout_s`: per-request timeout in seconds.
613+
/// - `retry_delay_s`: delay between attempts when not ready or on error.
614+
/// - `classify`: function to classify the response body.
615+
/// - `treat_unknown_as_ready`: if true, any non-starting response is treated as ready.
616+
pub fn wait_for_process_ready<F>(
617+
target: Address,
618+
request_body: Vec<u8>,
619+
timeout_s: u64,
620+
retry_delay_s: u64,
621+
mut classify: F,
622+
treat_unknown_as_ready: bool,
623+
) where
624+
F: FnMut(&[u8]) -> WaitClassification,
625+
{
626+
let mut attempt = 1;
627+
loop {
628+
match Request::to(target.clone())
629+
.body(request_body.clone())
630+
.send_and_await_response(timeout_s)
631+
{
632+
Ok(Ok(response)) => {
633+
let classification = classify(response.body());
634+
match classification {
635+
WaitClassification::Starting => {
636+
info!(
637+
"Target {} still starting (attempt {}), retrying in {}s",
638+
target, attempt, retry_delay_s
639+
);
640+
}
641+
WaitClassification::Ready => {
642+
info!("Target {} ready after {} attempt(s)", target, attempt);
643+
break;
644+
}
645+
WaitClassification::Unknown => {
646+
if treat_unknown_as_ready {
647+
info!(
648+
"Target {} responded with unknown payload, proceeding as ready",
649+
target
650+
);
651+
break;
652+
} else {
653+
info!(
654+
"Target {} responded with unknown payload, retrying in {}s",
655+
target, retry_delay_s
656+
);
657+
}
658+
}
659+
}
660+
}
661+
Ok(Err(e)) => {
662+
info!(
663+
"Error response from {} (attempt {}): {:?}, retrying in {}s",
664+
target, attempt, e, retry_delay_s
665+
);
666+
}
667+
Err(e) => {
668+
info!(
669+
"Failed to contact {} (attempt {}): {:?}, retrying in {}s",
670+
target, attempt, e, retry_delay_s
671+
);
672+
}
673+
}
674+
attempt += 1;
675+
std::thread::sleep(std::time::Duration::from_secs(retry_delay_s));
676+
}
677+
}
678+
597679
// For demonstration, we'll define them all in one place.
598680
// Make sure the signatures match the real function signatures you require!
599681
pub fn no_init_fn<S>(_state: &mut S) {

0 commit comments

Comments
 (0)