ito_core/
backend_coordination.rs1use std::path::Path;
9
10use ito_domain::backend::{
11 AllocateResult, ArchiveResult, ArtifactBundle, BackendArchiveClient, BackendLeaseClient,
12 BackendSyncClient, ClaimResult, PushResult, ReleaseResult,
13};
14
15use crate::backend_sync::map_backend_error;
16use crate::errors::{CoreError, CoreResult};
17
18pub fn claim_change(
20 lease_client: &dyn BackendLeaseClient,
21 change_id: &str,
22) -> CoreResult<ClaimResult> {
23 lease_client
24 .claim(change_id)
25 .map_err(|e| map_backend_error(e, "claim"))
26}
27
28pub fn release_change(
30 lease_client: &dyn BackendLeaseClient,
31 change_id: &str,
32) -> CoreResult<ReleaseResult> {
33 lease_client
34 .release(change_id)
35 .map_err(|e| map_backend_error(e, "release"))
36}
37
38pub fn allocate_change(lease_client: &dyn BackendLeaseClient) -> CoreResult<AllocateResult> {
40 lease_client
41 .allocate()
42 .map_err(|e| map_backend_error(e, "allocate"))
43}
44
45pub fn sync_pull(
47 sync_client: &dyn BackendSyncClient,
48 ito_path: &std::path::Path,
49 change_id: &str,
50 backup_dir: &std::path::Path,
51) -> CoreResult<ArtifactBundle> {
52 crate::backend_sync::pull_artifacts(sync_client, ito_path, change_id, backup_dir)
53}
54
55pub fn sync_push(
57 sync_client: &dyn BackendSyncClient,
58 ito_path: &std::path::Path,
59 change_id: &str,
60 backup_dir: &std::path::Path,
61) -> CoreResult<PushResult> {
62 crate::backend_sync::push_artifacts(sync_client, ito_path, change_id, backup_dir)
63}
64
65#[derive(Debug)]
67pub struct BackendArchiveOutcome {
68 pub specs_updated: Vec<String>,
70 pub archive_name: String,
72 pub backend_result: ArchiveResult,
74}
75
76pub fn archive_with_backend(
88 sync_client: &dyn BackendSyncClient,
89 archive_client: &dyn BackendArchiveClient,
90 ito_path: &Path,
91 change_id: &str,
92 backup_dir: &Path,
93 skip_specs: bool,
94) -> CoreResult<BackendArchiveOutcome> {
95 crate::backend_sync::pull_artifacts(sync_client, ito_path, change_id, backup_dir)?;
97
98 let specs_updated = if skip_specs {
100 Vec::new()
101 } else {
102 let spec_names = crate::archive::discover_change_specs(ito_path, change_id)?;
103 crate::archive::copy_specs_to_main(ito_path, change_id, &spec_names)?
104 };
105
106 let archive_name = crate::archive::generate_archive_name(change_id);
108 crate::archive::move_to_archive(ito_path, change_id, &archive_name)?;
109
110 let backend_result = archive_client
112 .mark_archived(change_id)
113 .map_err(|e| map_backend_error(e, "archive"))?;
114
115 Ok(BackendArchiveOutcome {
116 specs_updated,
117 archive_name,
118 backend_result,
119 })
120}
121
122pub fn is_backend_unavailable(err: &CoreError) -> bool {
126 match err {
127 CoreError::Process(msg) => msg.contains("Backend unavailable"),
128 _ => false,
129 }
130}
131
132#[cfg(test)]
133#[path = "backend_coordination_tests.rs"]
134mod backend_coordination_tests;