@ -1,4 +1,5 @@
using Octokit ;
using Microsoft.Extensions.Logging ;
using Octokit ;
using StabilityMatrix.Core.Attributes ;
using StabilityMatrix.Core.Attributes ;
using StabilityMatrix.Core.Database ;
using StabilityMatrix.Core.Database ;
using StabilityMatrix.Core.Models.Database ;
using StabilityMatrix.Core.Models.Database ;
@ -10,52 +11,37 @@ public class GithubApiCache : IGithubApiCache
{
{
private readonly ILiteDbContext dbContext ;
private readonly ILiteDbContext dbContext ;
private readonly IGitHubClient githubApi ;
private readonly IGitHubClient githubApi ;
private readonly ILogger < IGithubApiCache > logger ;
private readonly TimeSpan cacheDuration = TimeSpan . FromMinutes ( 1 5 ) ;
private readonly TimeSpan cacheDuration = TimeSpan . FromMinutes ( 1 5 ) ;
public GithubApiCache ( ILiteDbContext dbContext , IGitHubClient githubApi )
public GithubApiCache (
ILiteDbContext dbContext ,
IGitHubClient githubApi ,
ILogger < IGithubApiCache > logger
)
{
{
this . dbContext = dbContext ;
this . dbContext = dbContext ;
this . githubApi = githubApi ;
this . githubApi = githubApi ;
}
this . logger = logger ;
public async Task < Release ? > GetLatestRelease ( string username , string repository )
{
var cacheKey = $"Releases-{username}-{repository}" ;
var latestRelease = await dbContext . GetGithubCacheEntry ( cacheKey ) ;
if ( latestRelease ! = null & & ! IsCacheExpired ( latestRelease . LastUpdated ) )
{
return latestRelease . AllReleases . First ( ) ;
}
var allReleases = await githubApi . Repository . Release . GetAll ( username , repository ) ;
if ( allReleases = = null )
{
return null ;
}
var cacheEntry = new GithubCacheEntry
{
CacheKey = cacheKey ,
AllReleases = allReleases . OrderByDescending ( x = > x . CreatedAt )
} ;
await dbContext . UpsertGithubCacheEntry ( cacheEntry ) ;
return cacheEntry . AllReleases . First ( ) ;
}
}
public async Task < IEnumerable < Release > > GetAllReleases ( string username , string repository )
public async Task < IEnumerable < Release > > GetAllReleases ( string username , string repository )
{
{
var cacheKey = $"Releases-{username}-{repository}" ;
var cacheKey = $"Releases-{username}-{repository}" ;
var cacheEntry = await dbContext . GetGithubCacheEntry ( cacheKey ) ;
var cacheEntry = await dbContext . GetGithubCacheEntry ( cacheKey ) . ConfigureAwait ( false ) ;
if ( cacheEntry ! = null & & ! IsCacheExpired ( cacheEntry . LastUpdated ) )
if ( cacheEntry ! = null & & ! IsCacheExpired ( cacheEntry . LastUpdated ) )
{
{
return cacheEntry . AllReleases . OrderByDescending ( x = > x . CreatedAt ) ;
return cacheEntry . AllReleases . OrderByDescending ( x = > x . CreatedAt ) ;
}
}
var allReleases = await githubApi . Repository . Release . GetAll ( username , repository ) ;
try
{
var allReleases = await githubApi . Repository . Release
. GetAll ( username , repository )
. ConfigureAwait ( false ) ;
if ( allReleases = = null )
if ( allReleases = = null )
{
{
return new List < Release > ( ) . OrderByDescending ( x = > x . CreatedAt ) ;
return new List < Release > ( ) ;
}
}
var newCacheEntry = new GithubCacheEntry
var newCacheEntry = new GithubCacheEntry
@ -63,31 +49,48 @@ public class GithubApiCache : IGithubApiCache
CacheKey = cacheKey ,
CacheKey = cacheKey ,
AllReleases = allReleases . OrderByDescending ( x = > x . CreatedAt )
AllReleases = allReleases . OrderByDescending ( x = > x . CreatedAt )
} ;
} ;
await dbContext . UpsertGithubCacheEntry ( newCacheEntry ) ;
await dbContext . UpsertGithubCacheEntry ( newCacheEntry ) . ConfigureAwait ( false ) ;
return newCacheEntry . AllReleases ;
return newCacheEntry . AllReleases ;
}
}
catch ( ApiException ex )
{
logger . LogWarning ( ex , "Failed to get releases from Github API." ) ;
return cacheEntry ? . AllReleases . OrderByDescending ( x = > x . CreatedAt )
? ? Enumerable . Empty < Release > ( ) ;
}
}
public async Task < IEnumerable < Branch > > GetAllBranches ( string username , string repository )
public async Task < IEnumerable < Branch > > GetAllBranches ( string username , string repository )
{
{
var cacheKey = $"Branches-{username}-{repository}" ;
var cacheKey = $"Branches-{username}-{repository}" ;
var cacheEntry = await dbContext . GetGithubCacheEntry ( cacheKey ) ;
var cacheEntry = await dbContext . GetGithubCacheEntry ( cacheKey ) . ConfigureAwait ( false ) ;
if ( cacheEntry ! = null & & ! IsCacheExpired ( cacheEntry . LastUpdated ) )
if ( cacheEntry ! = null & & ! IsCacheExpired ( cacheEntry . LastUpdated ) )
{
{
return cacheEntry . Branches ;
return cacheEntry . Branches ;
}
}
var branches = await githubApi . Repository . Branch . GetAll ( username , repository ) ;
try
{
var branches = await githubApi . Repository . Branch
. GetAll ( username , repository )
. ConfigureAwait ( false ) ;
if ( branches = = null )
if ( branches = = null )
{
{
return new List < Branch > ( ) ;
return new List < Branch > ( ) ;
}
}
var newCacheEntry = new GithubCacheEntry { CacheKey = cacheKey , Branches = branches } ;
var newCacheEntry = new GithubCacheEntry { CacheKey = cacheKey , Branches = branches } ;
await dbContext . UpsertGithubCacheEntry ( newCacheEntry ) ;
await dbContext . UpsertGithubCacheEntry ( newCacheEntry ) . ConfigureAwait ( false ) ;
return newCacheEntry . Branches ;
return newCacheEntry . Branches ;
}
}
catch ( ApiException ex )
{
logger . LogWarning ( ex , "Failed to get branches from Github API." ) ;
return cacheEntry ? . Branches ? ? Enumerable . Empty < Branch > ( ) ;
}
}
public async Task < IEnumerable < GitCommit > ? > GetAllCommits (
public async Task < IEnumerable < GitCommit > ? > GetAllCommits (
string username ,
string username ,
@ -98,13 +101,16 @@ public class GithubApiCache : IGithubApiCache
)
)
{
{
var cacheKey = $"Commits-{username}-{repository}-{branch}-{page}-{perPage}" ;
var cacheKey = $"Commits-{username}-{repository}-{branch}-{page}-{perPage}" ;
var cacheEntry = await dbContext . GetGithubCacheEntry ( cacheKey ) ;
var cacheEntry = await dbContext . GetGithubCacheEntry ( cacheKey ) . ConfigureAwait ( false ) ;
if ( cacheEntry ! = null & & ! IsCacheExpired ( cacheEntry . LastUpdated ) )
if ( cacheEntry ! = null & & ! IsCacheExpired ( cacheEntry . LastUpdated ) )
{
{
return cacheEntry . Commits ;
return cacheEntry . Commits ;
}
}
var commits = await githubApi . Repository . Commit . GetAll (
try
{
var commits = await githubApi . Repository . Commit
. GetAll (
username ,
username ,
repository ,
repository ,
new CommitRequest { Sha = branch } ,
new CommitRequest { Sha = branch } ,
@ -114,7 +120,8 @@ public class GithubApiCache : IGithubApiCache
PageSize = perPage ,
PageSize = perPage ,
StartPage = page
StartPage = page
}
}
) ;
)
. ConfigureAwait ( false ) ;
if ( commits = = null )
if ( commits = = null )
{
{
@ -126,10 +133,16 @@ public class GithubApiCache : IGithubApiCache
CacheKey = cacheKey ,
CacheKey = cacheKey ,
Commits = commits . Select ( x = > new GitCommit { Sha = x . Sha } )
Commits = commits . Select ( x = > new GitCommit { Sha = x . Sha } )
} ;
} ;
await dbContext . UpsertGithubCacheEntry ( newCacheEntry ) ;
await dbContext . UpsertGithubCacheEntry ( newCacheEntry ) . ConfigureAwait ( false ) ;
return newCacheEntry . Commits ;
return newCacheEntry . Commits ;
}
}
catch ( ApiException ex )
{
logger . LogWarning ( ex , "Failed to get commits from Github API." ) ;
return cacheEntry ? . Commits ? ? Enumerable . Empty < GitCommit > ( ) ;
}
}
private bool IsCacheExpired ( DateTimeOffset expiration ) = >
private bool IsCacheExpired ( DateTimeOffset expiration ) = >
expiration . Add ( cacheDuration ) < DateTimeOffset . UtcNow ;
expiration . Add ( cacheDuration ) < DateTimeOffset . UtcNow ;