mirror of
https://seed.radicle.dev/rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5.git
synced 2026-11-15 15:50:38 +08:00
node: fetch refs announcements
Ref announcements contain the namespace (NID) and the SHA of the new `rad/sigrefs`. This information can be used by the fetch protocol to fetch only those `Oid`s for those namespaces. Add a new stage `SigrefsAnnouncement` that captures this behaviour by only asking for the advertised `Oid`s and updating the corresponding `rad/sigrefs` for each namespace. Note that this is a special case of the `SpecialRefs` stage and so the protocol chooses between these two by checking if there was announcement passed through. The following stage, `DataRefs`, stays the same. Note that this stage can only be activated via a `pull`, and `clone` stays the same. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::collections::VecDeque;
|
||||
use std::time;
|
||||
|
||||
use log::*;
|
||||
use radicle::git;
|
||||
use radicle::storage::refs::RefsAt;
|
||||
|
||||
use crate::prelude::*;
|
||||
@@ -29,8 +28,8 @@ pub enum Io {
|
||||
remote: NodeId,
|
||||
/// Namespaces being fetched.
|
||||
namespaces: Namespaces,
|
||||
/// If a refs announcements was made.
|
||||
refs_at: Option<HashMap<NodeId, git::Oid>>,
|
||||
/// If the node is fetching specific `rad/sigrefs`.
|
||||
refs_at: Option<Vec<RefsAt>>,
|
||||
/// Fetch timeout.
|
||||
timeout: time::Duration,
|
||||
},
|
||||
@@ -92,13 +91,7 @@ impl Outbox {
|
||||
refs_at: Vec<RefsAt>,
|
||||
timeout: time::Duration,
|
||||
) {
|
||||
let refs_at = {
|
||||
let refs = refs_at
|
||||
.into_iter()
|
||||
.map(|RefsAt { remote, at }| (remote, at))
|
||||
.collect::<HashMap<_, _>>();
|
||||
(!refs.is_empty()).then_some(refs)
|
||||
};
|
||||
let refs_at = (!refs_at.is_empty()).then_some(refs_at);
|
||||
self.io.push_back(Io::Fetch {
|
||||
rid,
|
||||
namespaces,
|
||||
|
||||
@@ -828,6 +828,7 @@ where
|
||||
rid,
|
||||
remote,
|
||||
timeout,
|
||||
refs_at,
|
||||
..
|
||||
} => {
|
||||
log::trace!(target: "wire", "Processing fetch for {rid} from {remote}..");
|
||||
@@ -850,6 +851,7 @@ where
|
||||
fetch: FetchRequest::Initiator {
|
||||
rid,
|
||||
remote,
|
||||
refs_at,
|
||||
timeout,
|
||||
},
|
||||
stream,
|
||||
|
||||
@@ -11,6 +11,7 @@ use crossbeam_channel as chan;
|
||||
|
||||
use radicle::identity::Id;
|
||||
use radicle::prelude::NodeId;
|
||||
use radicle::storage::refs::RefsAt;
|
||||
use radicle::storage::{ReadRepository, ReadStorage};
|
||||
use radicle::{crypto, git, Storage};
|
||||
use radicle_fetch::FetchLimit;
|
||||
@@ -95,6 +96,8 @@ pub enum FetchRequest {
|
||||
rid: Id,
|
||||
/// Remote peer we are interacting with.
|
||||
remote: NodeId,
|
||||
/// If this fetch is for a particular set of `rad/sigrefs`.
|
||||
refs_at: Option<Vec<RefsAt>>,
|
||||
/// Fetch timeout.
|
||||
timeout: time::Duration,
|
||||
},
|
||||
@@ -215,11 +218,12 @@ impl Worker {
|
||||
FetchRequest::Initiator {
|
||||
rid,
|
||||
remote,
|
||||
refs_at,
|
||||
// TODO: nowhere to use this currently
|
||||
timeout: _timeout,
|
||||
} => {
|
||||
log::debug!(target: "worker", "Worker processing outgoing fetch for {}", rid);
|
||||
let result = self.fetch(rid, remote, channels);
|
||||
let result = self.fetch(rid, remote, refs_at, channels);
|
||||
FetchResult::Initiator { rid, result }
|
||||
}
|
||||
FetchRequest::Responder { remote } => {
|
||||
@@ -265,6 +269,7 @@ impl Worker {
|
||||
&mut self,
|
||||
rid: Id,
|
||||
remote: NodeId,
|
||||
refs_at: Option<Vec<RefsAt>>,
|
||||
channels: channels::ChannelsFlush,
|
||||
) -> Result<fetch::FetchResult, FetchError> {
|
||||
let FetchConfig {
|
||||
@@ -292,7 +297,7 @@ impl Worker {
|
||||
channels,
|
||||
)?;
|
||||
|
||||
Ok(handle.fetch(rid, &self.storage, *limit, remote)?)
|
||||
Ok(handle.fetch(rid, &self.storage, *limit, remote, refs_at)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use radicle::crypto::PublicKey;
|
||||
use radicle::git::UserInfo;
|
||||
use radicle::prelude::Id;
|
||||
use radicle::storage::git::Repository;
|
||||
use radicle::storage::refs::RefsAt;
|
||||
use radicle::storage::{ReadStorage as _, RefUpdate, WriteRepository as _};
|
||||
use radicle::Storage;
|
||||
use radicle_fetch::{BlockList, FetchLimit, Tracked};
|
||||
@@ -59,6 +60,7 @@ impl Handle {
|
||||
storage: &Storage,
|
||||
limit: FetchLimit,
|
||||
remote: PublicKey,
|
||||
refs_at: Option<Vec<RefsAt>>,
|
||||
) -> Result<FetchResult, error::Fetch> {
|
||||
let result = match self {
|
||||
Self::Clone { mut handle, tmp } => {
|
||||
@@ -69,7 +71,7 @@ impl Handle {
|
||||
}
|
||||
Self::Pull { mut handle } => {
|
||||
log::debug!(target: "worker", "{} pulling from {remote}", handle.local());
|
||||
radicle_fetch::pull(&mut handle, limit, remote)?
|
||||
radicle_fetch::pull(&mut handle, limit, remote, refs_at)?
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user