Skip to main content

GitSource

Struct GitSource 

Source
pub struct GitSource { /* private fields */ }
Expand description

A file in a git repository, as a configuration source.

Built with GitSource::builder. Not Clone: the working directory is claimed by one source, and two clones fetching into it would interleave their ref updates. Wrap it in an Arc if two places need one.

Implementations§

Source§

impl GitSource

Source

pub fn builder(url: impl Into<String>) -> Builder

A source reading from the repository at url.

url is anything git understands: https://…, ssh://…, git@host:org/repo.git, or a local path.

Source

pub fn watch<F>( &self, watching: &Watching, interval: Duration, on_change: F, ) -> Result<(), Error>
where F: FnMut(Fetched) -> Result<(), Error>,

Calls on_change when the ref moves, checking every interval.

Polling, because git offers nothing better — and advertisement polling, because transferring a commit every tick to discover it has not changed would be a poor thing to do to a git host. Each tick is one handshake and one ref advertisement; only a ref that moved costs a transfer.

The current value is not delivered at startup, for the same reason a file watcher does not report an edit when it starts. Fetch first if the starting value matters, which it usually does:

sink.apply(source.fetch()?)?;
source.watch(&watching, Duration::from_secs(60), move |document| sink.apply(document))

A host that is away, a ref that has been deleted, a document that does not parse — none of those end the watch. It waits out the interval and tries again. stop is noticed within a quarter second regardless of how long interval is.

§A source reading several files can be watched

It is the only one in this family that can. Every other store refuses a watch on a set, and the reason is written down: waking on a change to one key and then re-reading key by key collects the new value of that key and whatever the others happen to be halfway through a deployment — a document that never existed at any instant, installed and then served until the next change.

Neither half of that applies here. What moves is a ref, and what a ref names is a commit — so the watch does not wake on one file, it wakes on the repository, and the re-read that follows takes every file out of that one commit’s tree. A deployment that writes four files in one commit is delivered as one document; a deployment that writes them in four commits is delivered as up to four documents, each of which is a state the repository really was in. There is no interleaving to be had.

The cost is the other direction, and it is the same cost a single-file watch has always had: a commit that touches nothing this source reads still moves the ref, so on_change is called with a document identical to the last one. A spurious delivery, never a torn one — dynamic-config diffs it and reports no changes.

§Errors

If the host refuses a credential that cannot be replaced — a token handed in as a constant is the same token next tick, so retrying it forever would be a hot loop against a host that may well start locking the account. A credential that came from a closure is refreshed and retried instead, and only ends the watch if the fresh one is refused too. Or if on_change returns an error, which ends the watch — so a caller that wants to survive a bad document should log it and return Ok.

Trait Implementations§

Source§

impl Debug for GitSource

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl RemoteSource for GitSource

Source§

fn watch_capability(&self) -> WatchCapability

Conditional: a ref advertisement says where the branch points without fetching the objects behind it.

Source§

fn fetch(&self) -> Result<Fetched, Error>

Reads the current document. Read more
Source§

fn describe(&self) -> String

How to name this source in an error or a report.
Source§

fn watch( &self, watching: &Watching, interval: Duration, on_change: &mut dyn FnMut(Fetched) -> Result<(), Error>, ) -> Result<(), Error>

Watches until the handle is dropped, calling on_change with every document that differs from the last one delivered. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more