History

[git-protocol] move everything into `blocking_io` for later translation…

…into async-io, as usual.

Sebastian Thiel committed 5 years ago

Commit fa033741 parent 0d39b5d12 files · +295 −254Browse files

Showing the changes to git-protocol/src/fetch/blocking_io/delegate.rs (1 of 12 files). Show all

Unified · Split

git-protocol/src/fetch/blocking_io/delegate.rs+100−0
@@ -0,0 +1,100 @@
1+use crate::fetch::{Arguments, Ref, Response};
2+use bstr::BString;
3+use git_features::progress::Progress;
4+use git_transport::client::Capabilities;
5+use std::io;
6+
7+/// Defines what to do next after certain [`Delegate`] operations.
8+#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
9+pub enum Action {
10+ /// Continue the typical flow of operations in this flow.
11+ Continue,
12+ /// Close the connection without making any further requests.
13+ Close,
14+}
15+
16+/// The protocol delegate is the bare minimal interface needed to fully control the [`fetch`][crate::fetch()] operation.
17+///
18+/// Implementations of this trait are controlled by code with intricate knowledge about how fetching works in protocol version V1 and V2,
19+/// so you don't have to.
20+/// Everything is tucked away behind type-safety so 'nothing can go wrong'©. Runtime assertions assure invalid
21+/// features or arguments don't make it to the server in the first place.
22+/// Please note that this trait mostly corresponds to what V2 would look like, even though V1 is supported as well.
23+pub trait Delegate {
24+ /// Called before invoking 'ls-refs' on the server to allow providing it with additional `arguments` and to enable `features`.
25+ ///
26+ /// Note that some arguments are preset based on typical use, and `features` are preset to maximize options.
27+ /// The `server` capabilities can be used to see which additional capabilities the server supports as per the handshake which happened prior.
28+ /// Note that this is called only if we are using protocol version 2.
29+ fn prepare_ls_refs(
30+ &mut self,
31+ _server: &Capabilities,
32+ _arguments: &mut Vec<BString>,
33+ _features: &mut Vec<(&str, Option<&str>)>,
34+ ) {
35+ }
36+
37+ /// Called before invoking the 'fetch' interaction with `features` pre-filled for typical use
38+ /// and to maximize capabilities to allow aborting an interaction early.
39+ ///
40+ /// `refs` is a list of known references on the remote based on the handshake or a prior call to ls_refs.
41+ /// These can be used to abort early in case the refs are already known here.
42+ ///
43+ /// As there will be another call allowing to post arguments conveniently in the correct format, i.e. `want hex-oid`,
44+ /// there is no way to set arguments at this time.
45+ ///
46+ /// `version` is the actually supported version as reported by the server, which is relevant in case the server requested a downgrade.
47+ /// `server` capabilities is a list of features the server supports for your information, along with enabled `features` that the server knows about.
48+ fn prepare_fetch(
49+ &mut self,
50+ _version: git_transport::Protocol,
51+ _server: &Capabilities,
52+ _features: &mut Vec<(&str, Option<&str>)>,
53+ _refs: &[Ref],
54+ ) -> Action {
55+ Action::Continue
56+ }
57+
58+ /// A method called repeatedly to negotiate the objects to receive in [`receive_pack(…)`][Delegate::receive_pack()].
59+ ///
60+ /// The first call has `previous` set to `None` as there was no previous response. Every call that follows `previous`
61+ /// will be set to `Some`.
62+ ///
63+ /// ### If `previous` is `None`…
64+ ///
65+ /// Given a list of `arguments` to populate with wants, shallows, filters and other contextual information to be
66+ /// sent to the server. This method is called once.
67+ /// Send the objects you `have` have afterwards based on the tips of your refs, in preparation to walk down their parents
68+ /// with each call to `negotiate` to find the common base(s).
69+ ///
70+ /// Note that you should not `want` and object that you already have.
71+ /// `refs` are the the tips of on the server side, effectively the latest objects _they_ have.
72+ ///
73+ /// Return `Action::Close` if you know that there are no `haves` on your end to allow the server to send all of its objects
74+ /// as is the case during initial clones.
75+ ///
76+ /// ### If `previous` is `Some`…
77+ ///
78+ /// Populate `arguments` with the objects you `have` starting from the tips of _your_ refs, taking into consideration
79+ /// the `previous` response of the server to see which objects they acknowledged to have. You have to maintain
80+ /// enough state to be able to walk down from your tips on each call, if they are not in common, and keep setting `have`
81+ /// for those which are in common if that helps teaching the server about our state and to acknowledge their existence on _their_ end.
82+ /// This method is called until the other side signals they are ready to send a pack.
83+ /// Return `Action::Close` if you want to give up before finding a common base. This can happen if the remote repository
84+ /// has radically changed so there are no bases, or they are very far in the past, causing all objects to be sent.
85+ fn negotiate(&mut self, refs: &[Ref], arguments: &mut Arguments, previous: Option<&Response>) -> Action;
86+
87+ /// Receive a pack provided from the given `input`.
88+ ///
89+ /// Use `progress` to emit your own progress messages when decoding the pack.
90+ ///
91+ /// `refs` of the remote side are provided for convenience, along with the parsed `previous` response in case you want
92+ /// to check additional acks.
93+ fn receive_pack(
94+ &mut self,
95+ input: impl io::BufRead,
96+ progress: impl Progress,
97+ refs: &[Ref],
98+ previous: &Response,
99+ ) -> io::Result<()>;
100+}