mirror of
https://seed.radicle.dev/rad:zwTxygwuz5LDGBq255RA2CbNGrz8.git
synced 2026-10-18 19:30:29 +08:00
feat: announce COB changes to other nodes
Add a function to `src/cob.rs` to announce changes to other nodes. This is a separate commit as it's the most risky one so I want to make it easy to revert. Signed-off-by: Lars Wirzenius <liw@liw.fi>
This commit is contained in:
+49
-1
@@ -5,13 +5,17 @@
|
||||
//! the creation of a "job COB" for every CI run, and updating it when
|
||||
//! the run ends so that the COB captures the result of the run.
|
||||
|
||||
use std::str::FromStr;
|
||||
use std::{collections::BTreeSet, str::FromStr, time::Duration};
|
||||
|
||||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
|
||||
use radicle::{
|
||||
git::Oid,
|
||||
node::{
|
||||
sync::{Announcer, AnnouncerConfig, ReplicationFactor},
|
||||
Handle, Node,
|
||||
},
|
||||
prelude::{Profile, ReadStorage, RepoId},
|
||||
storage::git::Repository,
|
||||
};
|
||||
@@ -33,6 +37,7 @@ pub fn create_job(repo_id: RepoId, oid: Oid) -> Result<(), JobError> {
|
||||
match job_for_commit(&jobs, oid) {
|
||||
Err(JobError::NoJob(_)) => {
|
||||
let job = jobs.create(oid, &signer).map_err(JobError::CreateJob)?;
|
||||
announce(&profile, repo_id)?;
|
||||
logger::job_create(&repo_id, &oid, job.id());
|
||||
Ok(())
|
||||
}
|
||||
@@ -56,6 +61,7 @@ pub fn create_run(repo_id: RepoId, oid: Oid, run_id: RunId, url: &Url) -> Result
|
||||
let mut job = jobs.get_mut(&job_id).map_err(JobError::GetJobMut)?;
|
||||
job.run(uuid, url.clone(), &signer)
|
||||
.map_err(JobError::AddRun)?;
|
||||
announce(&profile, repo_id)?;
|
||||
|
||||
logger::job_run_create(job_id, uuid);
|
||||
Ok(())
|
||||
@@ -83,6 +89,7 @@ fn finish(repo_id: RepoId, oid: Oid, run_id: RunId, reason: Reason) -> Result<()
|
||||
let mut job = jobs.get_mut(&job_id).map_err(JobError::GetJobMut)?;
|
||||
job.finish(uuid, reason, &signer)
|
||||
.map_err(JobError::Finish)?;
|
||||
announce(&profile, repo_id)?;
|
||||
|
||||
logger::job_run_finished(job_id, uuid, reason);
|
||||
Ok(())
|
||||
@@ -118,6 +125,38 @@ fn job_for_commit<'a>(jobs: &Jobs<'a, Repository>, wanted: Oid) -> Result<JobId,
|
||||
Err(JobError::NoJob(wanted))
|
||||
}
|
||||
|
||||
fn announce(profile: &Profile, repo_id: RepoId) -> Result<(), JobError> {
|
||||
const TIMEOUT: Duration = Duration::from_millis(5000);
|
||||
|
||||
let mut node = Node::new(profile.home.socket());
|
||||
|
||||
let (synced, unsynced) = node.seeds(repo_id).map_err(JobError::Seeds)?.iter().fold(
|
||||
(BTreeSet::new(), BTreeSet::new()),
|
||||
|(mut synced, mut unsynced), seed| {
|
||||
if seed.is_synced() {
|
||||
synced.insert(seed.nid);
|
||||
} else {
|
||||
unsynced.insert(seed.nid);
|
||||
}
|
||||
(synced, unsynced)
|
||||
},
|
||||
);
|
||||
|
||||
let announcer = Announcer::new(AnnouncerConfig::public(
|
||||
*profile.id(),
|
||||
ReplicationFactor::MustReach(1),
|
||||
BTreeSet::new(),
|
||||
synced,
|
||||
unsynced,
|
||||
))
|
||||
.map_err(|_| JobError::Announcer)?;
|
||||
|
||||
node.announce(repo_id, TIMEOUT, announcer, |_, _| ())
|
||||
.map_err(JobError::Announce)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors from managing job COBs.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum JobError {
|
||||
@@ -159,4 +198,13 @@ pub enum JobError {
|
||||
|
||||
#[error("a job for Git object {0} already exists")]
|
||||
JobExists(Oid),
|
||||
|
||||
#[error("failed to get seeds for node")]
|
||||
Seeds(#[source] radicle::node::Error),
|
||||
|
||||
#[error("failed to announce COB change")]
|
||||
Announce(#[source] radicle::node::Error),
|
||||
|
||||
#[error("failed to create a COB announcer")]
|
||||
Announcer,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user