Track 'fully-restored' by tracking each cache restore

Instead of tracking a single 'fully-restored' flag, track the restore status of each
cache entry restore. If any of these are requested but not restored, then the overall
Gradle User Home cache is not fully restored.

Added special handling for the case when zero artifact bundles are set: this is used
in tests to simulate a not-fully-restored state.
This commit is contained in:
Daz DeBoer 2021-10-29 10:19:35 -06:00
parent 9edc2a11bd
commit 8ba5a0033b
No known key found for this signature in database
GPG key ID: DD6B9F0B06683D5D
3 changed files with 97 additions and 31 deletions

View file

@ -106,10 +106,44 @@ class CacheKey {
}
export class CachingReport {
fullyRestored: boolean
cacheEntryReports: CacheEntryReport[] = []
constructor(fullyRestored: boolean) {
this.fullyRestored = fullyRestored
get fullyRestored(): boolean {
return this.cacheEntryReports.every(x => !x.wasRequestedButNotRestored())
}
addEntryReport(name: string): CacheEntryReport {
const report = new CacheEntryReport(name)
this.cacheEntryReports.push(report)
return report
}
}
export class CacheEntryReport {
entryName: string
requestedKey: string | undefined
requestedRestoreKeys: string[] | undefined
restoredKey: string | undefined
restoredSize: number | undefined
savedKey: string | undefined
savedSize: number | undefined
constructor(entryName: string) {
this.entryName = entryName
}
wasRequestedButNotRestored(): boolean {
return this.requestedKey !== undefined && this.restoredKey === undefined
}
markRequested(key: string, restoreKeys: string[] = []): void {
this.requestedKey = key
this.requestedRestoreKeys = restoreKeys
}
markRestored(key: string): void {
this.restoredKey = key
}
}
@ -129,13 +163,15 @@ export abstract class AbstractCache {
this.cacheDebuggingEnabled = isCacheDebuggingEnabled()
}
async restore(): Promise<CachingReport> {
async restore(report: CachingReport): Promise<void> {
if (this.cacheOutputExists()) {
core.info(`${this.cacheDescription} already exists. Not restoring from cache.`)
return new CachingReport(false)
return
}
const cacheKey = this.prepareCacheKey()
const entryReport = report.addEntryReport(this.cacheName)
entryReport.markRequested(cacheKey.key, cacheKey.restoreKeys)
this.debug(
`Requesting ${this.cacheDescription} with
@ -147,21 +183,18 @@ export abstract class AbstractCache {
if (!cacheResult) {
core.info(`${this.cacheDescription} cache not found. Will start with empty.`)
return new CachingReport(false)
return
}
core.saveState(this.cacheResultStateKey, cacheResult)
entryReport.markRestored(cacheResult)
core.info(`Restored ${this.cacheDescription} from cache key: ${cacheResult}`)
const report = new CachingReport(true)
try {
await this.afterRestore(report)
} catch (error) {
core.warning(`Restore ${this.cacheDescription} failed in 'afterRestore': ${error}`)
}
return report
}
prepareCacheKey(): CacheKey {