Skip to content

Commit 0c3a1fc

Browse files
authored
Merge pull request #176 from hyperware-ai/hf/tweak-wait-for-process-ready
tweak `wait_for_process_ready`
2 parents 8cc0079 + f5a7adc commit 0c3a1fc

File tree

3 files changed

+110
-83
lines changed

3 files changed

+110
-83
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/hyperapp.rs

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -594,88 +594,6 @@ 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-
679597
// For demonstration, we'll define them all in one place.
680598
// Make sure the signatures match the real function signatures you require!
681599
pub fn no_init_fn<S>(_state: &mut S) {

src/lib.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,115 @@ pub fn eval_our(address: &Address) -> Address {
364364
address
365365
}
366366

367+
/// Classification for readiness polling of another process.
368+
#[derive(Debug, PartialEq, Eq)]
369+
pub enum WaitClassification {
370+
/// The target responded but indicated it is still starting up.
371+
Starting,
372+
/// The target is ready (or responded with a payload we consider ready).
373+
Ready,
374+
/// The target responded with an unknown payload.
375+
Unknown,
376+
}
377+
378+
/// Poll a target process until it reports ready while blocking.
379+
///
380+
/// - `target`: process address to poll (e.g., hypermap-cacher).
381+
/// - `request_body`: request payload to send each attempt.
382+
/// - `timeout_s`: per-request timeout in seconds.
383+
/// - `retry_delay_s`: delay between attempts when not ready or on error.
384+
/// - `classify`: function to classify the response body.
385+
/// - `treat_unknown_as_ready`: if true, any non-starting response is treated as ready.
386+
/// - `max_attempts`: number of attempts before continuing without a ready response.
387+
pub fn wait_for_process_ready<F>(
388+
target: Address,
389+
request_body: Vec<u8>,
390+
timeout_s: u64,
391+
retry_delay_s: u64,
392+
mut classify: F,
393+
treat_unknown_as_ready: bool,
394+
max_attempts: Option<u32>,
395+
) where
396+
F: FnMut(&[u8]) -> WaitClassification,
397+
{
398+
let mut attempt = 1;
399+
loop {
400+
let mut fail_message_suffix = format!(", retrying in {retry_delay_s}s");
401+
if let Some(ma) = max_attempts {
402+
if attempt >= ma {
403+
fail_message_suffix = ", abandoning waiting and proceeding as if ready".to_string()
404+
}
405+
}
406+
407+
match Request::to(target.clone())
408+
.body(request_body.clone())
409+
.send_and_await_response(timeout_s)
410+
{
411+
Ok(Ok(response)) => {
412+
let classification = classify(response.body());
413+
match classification {
414+
WaitClassification::Starting => {
415+
crate::print_to_terminal(
416+
2,
417+
&format!(
418+
"Target {} still starting (attempt {}){}",
419+
target, attempt, fail_message_suffix
420+
),
421+
);
422+
}
423+
WaitClassification::Ready => {
424+
crate::print_to_terminal(
425+
2,
426+
&format!("Target {} ready after {} attempt(s)", target, attempt),
427+
);
428+
break;
429+
}
430+
WaitClassification::Unknown => {
431+
if treat_unknown_as_ready {
432+
crate::print_to_terminal(
433+
2,
434+
&format!(
435+
"Target {} responded with unknown payload, proceeding as ready",
436+
target
437+
),
438+
);
439+
break;
440+
} else {
441+
crate::print_to_terminal(
442+
2,
443+
&format!(
444+
"Target {} responded with unknown payload{}",
445+
target, fail_message_suffix
446+
),
447+
);
448+
}
449+
}
450+
}
451+
}
452+
Ok(Err(e)) => {
453+
crate::print_to_terminal(
454+
2,
455+
&format!(
456+
"Error response from {} (attempt {}): {:?}{}",
457+
target, attempt, e, fail_message_suffix
458+
),
459+
);
460+
}
461+
Err(e) => {
462+
crate::print_to_terminal(
463+
2,
464+
&format!(
465+
"Failed to contact {} (attempt {}): {:?}{}",
466+
target, attempt, e, fail_message_suffix
467+
),
468+
);
469+
}
470+
}
471+
attempt += 1;
472+
std::thread::sleep(std::time::Duration::from_secs(retry_delay_s));
473+
}
474+
}
475+
367476
/// The `Spawn!()` macro is defined here as a no-op.
368477
/// However, in practice, `kit build` will rewrite it during pre-processing.
369478
///

0 commit comments

Comments
 (0)