Start the repository owner or reconnect when another process won election.
(repository: &Path)
| 784 | |
| 785 | /// Start the repository owner or reconnect when another process won election. |
| 786 | pub(crate) fn start_or_reconnect(repository: &Path) -> anyhow::Result<OwnerResponse> { |
| 787 | if let Ok(response) = request(repository, OwnerRequest::Ping) { |
| 788 | return Ok(response); |
| 789 | } |
| 790 | |
| 791 | let executable = std::env::current_exe().context("failed to locate atomic executable")?; |
| 792 | let mut command = ProcessCommand::new(executable); |
| 793 | command |
| 794 | .arg("agent") |
| 795 | .arg("database-owner") |
| 796 | .arg("serve") |
| 797 | .arg("--repository") |
| 798 | .arg(repository) |
| 799 | .stdin(Stdio::null()) |
| 800 | .stdout(Stdio::null()) |
| 801 | .stderr(Stdio::null()); |
| 802 | configure_detached(&mut command)?; |
| 803 | let mut child = command |
| 804 | .spawn() |
| 805 | .context("failed to spawn repository database owner")?; |
| 806 | |
| 807 | for _ in 0..START_ATTEMPTS { |
| 808 | if let Ok(response) = request(repository, OwnerRequest::Ping) { |
| 809 | return Ok(response); |
| 810 | } |
| 811 | if let Some(status) = child |
| 812 | .try_wait() |
| 813 | .context("failed to inspect database-owner bootstrap")? |
| 814 | { |
| 815 | // A concurrent bootstrap may have won election. Give its endpoint |
| 816 | // the remainder of the retry window before reporting our exit. |
| 817 | if !status.success() { |
| 818 | for _ in 0..START_ATTEMPTS { |
| 819 | if let Ok(response) = request(repository, OwnerRequest::Ping) { |
| 820 | return Ok(response); |
| 821 | } |
| 822 | std::thread::sleep(START_RETRY_DELAY); |
| 823 | } |
| 824 | return Err(anyhow!("database owner exited during bootstrap: {status}")); |
| 825 | } |
| 826 | } |
| 827 | std::thread::sleep(START_RETRY_DELAY); |
| 828 | } |
| 829 | |
| 830 | Err(anyhow!( |
| 831 | "database owner did not become healthy before timeout" |
| 832 | )) |
| 833 | } |
| 834 | |
| 835 | fn request_with_reconnect( |
| 836 | repository: &Path, |
no test coverage detected