Skip to main content

ReleaseDatesCache

Struct ReleaseDatesCache 

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

Memoized, best-effort GitHub Releases publish-date cache.

Shared by every ecosystem that resolves package versions from GitHub tags but wants to enrich them with a release’s published_at (deps-swift, deps-github-actions). Fetching /releases is a second, separate request from the tags fetch that produces the version list itself — Self::fetch is meant to run concurrently with that tags fetch (e.g. via tokio::join!) and is infallible by construction, so it can never perturb the tags fetch’s error propagation. A caller joins the returned map onto its own already-fetched, ecosystem-specific version list by normalize_taging each version’s tag text (#223).

One cache may safely be shared across Self::fetch calls passing different GithubTagsClients (e.g. a caller that swaps in a mock client under test): entries are keyed on (client.api_base(), name), not name alone, so a hit fetched via one origin’s client can never serve a read for another origin (#486 critic M1).

Implementations§

Source§

impl ReleaseDatesCache

Source

pub fn new() -> Self

Creates an empty cache.

§Examples
use deps_core::github::ReleaseDatesCache;

let _cache = ReleaseDatesCache::new();
Source

pub async fn fetch( &self, github: &GithubTagsClient, name: &str, ecosystem: &'static str, ) -> Arc<HashMap<String, PublishTime>>

Fetches the newest ~100 GitHub Releases for name (owner/repo) via github, and returns a normalized-tag -> publish-time map, memoized behind a per-package TTL.

Best-effort by construction (#223): a malformed identity or a validation failure returns an empty map with zero requests; a missing GITHUB_TOKEN returns an empty map (logged once per cache instance, naming ecosystem) with zero requests; any live-fetch error (network, rate limit, unparseable body, or exceeding the fetch timeout) returns an empty map, memoized under the short error TTL rather than the positive success TTL. Never propagates an error — a caller running this under tokio::join! alongside a tags fetch must not have that fetch perturbed by a release-dates failure.

Runs its own validate_owner_repo guard, independent of any validation the tags fetch performs: under a tokio::join! that guard may not run first, and this method interpolates name into an api.github.com path of its own (#223 M6).

§Examples

A malformed identity is rejected before any request is built — deterministic and network-free, so it doubles as a runnable example:

use deps_core::HttpCache;
use deps_core::github::{GithubTagsClient, ReleaseDatesCache};
use std::sync::Arc;

let cache = ReleaseDatesCache::new();
let github = GithubTagsClient::new(Arc::new(HttpCache::new()));
let dates = cache.fetch(&github, "not-a-valid-owner-repo", "Example").await;
assert!(dates.is_empty());

Trait Implementations§

Source§

impl Default for ReleaseDatesCache

Source§

fn default() -> ReleaseDatesCache

Returns the “default value” for a type. 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.

§

impl<T> Instrument for T

§

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

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

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.

§

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

§

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
§

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, 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.
§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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