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