mirror of
https://github.com/gradle/actions.git
synced 2025-08-23 18:31:28 +08:00
parent
d156388eb1
commit
e5c1381176
@ -110,10 +110,12 @@ export class CacheEntryListener {
|
|||||||
requestedRestoreKeys: string[] | undefined
|
requestedRestoreKeys: string[] | undefined
|
||||||
restoredKey: string | undefined
|
restoredKey: string | undefined
|
||||||
restoredSize: number | undefined
|
restoredSize: number | undefined
|
||||||
|
restoredTime: number | undefined
|
||||||
notRestored: string | undefined
|
notRestored: string | undefined
|
||||||
|
|
||||||
savedKey: string | undefined
|
savedKey: string | undefined
|
||||||
savedSize: number | undefined
|
savedSize: number | undefined
|
||||||
|
savedTime: number | undefined
|
||||||
notSaved: string | undefined
|
notSaved: string | undefined
|
||||||
|
|
||||||
constructor(entryName: string) {
|
constructor(entryName: string) {
|
||||||
@ -130,9 +132,10 @@ export class CacheEntryListener {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
markRestored(key: string, size: number | undefined): CacheEntryListener {
|
markRestored(key: string, size: number | undefined, time: number): CacheEntryListener {
|
||||||
this.restoredKey = key
|
this.restoredKey = key
|
||||||
this.restoredSize = size
|
this.restoredSize = size
|
||||||
|
this.restoredTime = time
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,9 +144,10 @@ export class CacheEntryListener {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
markSaved(key: string, size: number | undefined): CacheEntryListener {
|
markSaved(key: string, size: number | undefined, time: number): CacheEntryListener {
|
||||||
this.savedKey = key
|
this.savedKey = key
|
||||||
this.savedSize = size
|
this.savedSize = size
|
||||||
|
this.savedTime = time
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,14 +186,16 @@ ${renderEntryTable(entries)}
|
|||||||
function renderEntryTable(entries: CacheEntryListener[]): string {
|
function renderEntryTable(entries: CacheEntryListener[]): string {
|
||||||
return `
|
return `
|
||||||
<table>
|
<table>
|
||||||
<tr><td></td><th>Count</th><th>Total Size (Mb)</th></tr>
|
<tr><td></td><th>Count</th><th>Total Size (Mb)</th><th>Total Time (ms)</tr>
|
||||||
<tr><td>Entries Restored</td>
|
<tr><td>Entries Restored</td>
|
||||||
<td>${getCount(entries, e => e.restoredSize)}</td>
|
<td>${getCount(entries, e => e.restoredSize)}</td>
|
||||||
<td>${getSize(entries, e => e.restoredSize)}</td>
|
<td>${getSize(entries, e => e.restoredSize)}</td>
|
||||||
|
<td>${getTime(entries, e => e.restoredTime)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td>Entries Saved</td>
|
<tr><td>Entries Saved</td>
|
||||||
<td>${getCount(entries, e => e.savedSize)}</td>
|
<td>${getCount(entries, e => e.savedSize)}</td>
|
||||||
<td>${getSize(entries, e => e.savedSize)}</td>
|
<td>${getSize(entries, e => e.savedSize)}</td>
|
||||||
|
<td>${getTime(entries, e => e.savedTime)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
`
|
`
|
||||||
@ -202,9 +208,11 @@ function renderEntryDetails(listener: CacheListener): string {
|
|||||||
Requested Key : ${entry.requestedKey ?? ''}
|
Requested Key : ${entry.requestedKey ?? ''}
|
||||||
Restored Key : ${entry.restoredKey ?? ''}
|
Restored Key : ${entry.restoredKey ?? ''}
|
||||||
Size: ${formatSize(entry.restoredSize)}
|
Size: ${formatSize(entry.restoredSize)}
|
||||||
|
Time: ${formatTime(entry.restoredTime)}
|
||||||
${getRestoredMessage(entry, listener.cacheWriteOnly)}
|
${getRestoredMessage(entry, listener.cacheWriteOnly)}
|
||||||
Saved Key : ${entry.savedKey ?? ''}
|
Saved Key : ${entry.savedKey ?? ''}
|
||||||
Size: ${formatSize(entry.savedSize)}
|
Size: ${formatSize(entry.savedSize)}
|
||||||
|
Time: ${formatTime(entry.savedTime)}
|
||||||
${getSavedMessage(entry, listener.cacheReadOnly)}
|
${getSavedMessage(entry, listener.cacheReadOnly)}
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
@ -264,9 +272,23 @@ function getSize(
|
|||||||
return Math.round(bytes / (1024 * 1024))
|
return Math.round(bytes / (1024 * 1024))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTime(
|
||||||
|
cacheEntries: CacheEntryListener[],
|
||||||
|
predicate: (value: CacheEntryListener) => number | undefined
|
||||||
|
): number {
|
||||||
|
return cacheEntries.map(e => predicate(e) ?? 0).reduce((p, v) => p + v, 0)
|
||||||
|
}
|
||||||
|
|
||||||
function formatSize(bytes: number | undefined): string {
|
function formatSize(bytes: number | undefined): string {
|
||||||
if (bytes === undefined || bytes === 0) {
|
if (bytes === undefined || bytes === 0) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`
|
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatTime(ms: number | undefined): string {
|
||||||
|
if (ms === undefined || ms === 0) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
return `${ms} ms`
|
||||||
|
}
|
||||||
|
@ -38,13 +38,14 @@ export async function restoreCache(
|
|||||||
): Promise<cache.CacheEntry | undefined> {
|
): Promise<cache.CacheEntry | undefined> {
|
||||||
listener.markRequested(cacheKey, cacheRestoreKeys)
|
listener.markRequested(cacheKey, cacheRestoreKeys)
|
||||||
try {
|
try {
|
||||||
|
const startTime = Date.now()
|
||||||
// Only override the read timeout if the SEGMENT_DOWNLOAD_TIMEOUT_MINS env var has NOT been set
|
// Only override the read timeout if the SEGMENT_DOWNLOAD_TIMEOUT_MINS env var has NOT been set
|
||||||
const cacheRestoreOptions = process.env[SEGMENT_DOWNLOAD_TIMEOUT_VAR]
|
const cacheRestoreOptions = process.env[SEGMENT_DOWNLOAD_TIMEOUT_VAR]
|
||||||
? {}
|
? {}
|
||||||
: {segmentTimeoutInMs: SEGMENT_DOWNLOAD_TIMEOUT_DEFAULT}
|
: {segmentTimeoutInMs: SEGMENT_DOWNLOAD_TIMEOUT_DEFAULT}
|
||||||
const restoredEntry = await cache.restoreCache(cachePath, cacheKey, cacheRestoreKeys, cacheRestoreOptions)
|
const restoredEntry = await cache.restoreCache(cachePath, cacheKey, cacheRestoreKeys, cacheRestoreOptions)
|
||||||
if (restoredEntry !== undefined) {
|
if (restoredEntry !== undefined) {
|
||||||
listener.markRestored(restoredEntry.key, restoredEntry.size)
|
listener.markRestored(restoredEntry.key, restoredEntry.size, Date.now() - startTime)
|
||||||
}
|
}
|
||||||
return restoredEntry
|
return restoredEntry
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -56,8 +57,9 @@ export async function restoreCache(
|
|||||||
|
|
||||||
export async function saveCache(cachePath: string[], cacheKey: string, listener: CacheEntryListener): Promise<void> {
|
export async function saveCache(cachePath: string[], cacheKey: string, listener: CacheEntryListener): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
const startTime = Date.now()
|
||||||
const savedEntry = await cache.saveCache(cachePath, cacheKey)
|
const savedEntry = await cache.saveCache(cachePath, cacheKey)
|
||||||
listener.markSaved(savedEntry.key, savedEntry.size)
|
listener.markSaved(savedEntry.key, savedEntry.size, Date.now() - startTime)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof cache.ReserveCacheError) {
|
if (error instanceof cache.ReserveCacheError) {
|
||||||
listener.markAlreadyExists(cacheKey)
|
listener.markAlreadyExists(cacheKey)
|
||||||
|
@ -134,7 +134,7 @@ abstract class AbstractEntryExtractor {
|
|||||||
): Promise<ExtractedCacheEntry> {
|
): Promise<ExtractedCacheEntry> {
|
||||||
const restoredEntry = await restoreCache([pattern], cacheKey, [], listener)
|
const restoredEntry = await restoreCache([pattern], cacheKey, [], listener)
|
||||||
if (restoredEntry) {
|
if (restoredEntry) {
|
||||||
core.info(`Restored ${artifactType} with key ${cacheKey} to ${pattern}`)
|
core.info(`Restored ${artifactType} with key ${cacheKey} to ${pattern} in ${listener.restoredTime}ms`)
|
||||||
return new ExtractedCacheEntry(artifactType, pattern, cacheKey)
|
return new ExtractedCacheEntry(artifactType, pattern, cacheKey)
|
||||||
} else {
|
} else {
|
||||||
core.info(`Did not restore ${artifactType} with key ${cacheKey} to ${pattern}`)
|
core.info(`Did not restore ${artifactType} with key ${cacheKey} to ${pattern}`)
|
||||||
@ -232,8 +232,8 @@ abstract class AbstractEntryExtractor {
|
|||||||
cacheDebug(`No change to previously restored ${artifactType}. Not saving.`)
|
cacheDebug(`No change to previously restored ${artifactType}. Not saving.`)
|
||||||
entryListener.markNotSaved('contents unchanged')
|
entryListener.markNotSaved('contents unchanged')
|
||||||
} else {
|
} else {
|
||||||
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`)
|
|
||||||
await saveCache([pattern], cacheKey, entryListener)
|
await saveCache([pattern], cacheKey, entryListener)
|
||||||
|
core.info(`Saved ${artifactType} with key ${cacheKey} from ${pattern} in ${entryListener.savedTime}ms`)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const file of matchingFiles) {
|
for (const file of matchingFiles) {
|
||||||
|
@ -60,7 +60,8 @@ export class GradleUserHomeCache {
|
|||||||
restoreKeys:[${cacheKey.restoreKeys}]`
|
restoreKeys:[${cacheKey.restoreKeys}]`
|
||||||
)
|
)
|
||||||
|
|
||||||
const cacheResult = await restoreCache(this.getCachePath(), cacheKey.key, cacheKey.restoreKeys, entryListener)
|
const cachePath = this.getCachePath()
|
||||||
|
const cacheResult = await restoreCache(cachePath, cacheKey.key, cacheKey.restoreKeys, entryListener)
|
||||||
if (!cacheResult) {
|
if (!cacheResult) {
|
||||||
core.info(`${this.cacheDescription} cache not found. Will initialize empty.`)
|
core.info(`${this.cacheDescription} cache not found. Will initialize empty.`)
|
||||||
return
|
return
|
||||||
@ -68,7 +69,9 @@ export class GradleUserHomeCache {
|
|||||||
|
|
||||||
core.saveState(RESTORED_CACHE_KEY_KEY, cacheResult.key)
|
core.saveState(RESTORED_CACHE_KEY_KEY, cacheResult.key)
|
||||||
|
|
||||||
core.info(`Restored ${this.cacheDescription} from cache key: ${cacheResult.key}`)
|
core.info(
|
||||||
|
`Restored ${this.cacheDescription} with key ${cacheResult.key} to ${cachePath.join()} in ${entryListener.restoredTime}ms`
|
||||||
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.afterRestore(listener)
|
await this.afterRestore(listener)
|
||||||
@ -120,9 +123,11 @@ export class GradleUserHomeCache {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`)
|
|
||||||
const cachePath = this.getCachePath()
|
const cachePath = this.getCachePath()
|
||||||
await saveCache(cachePath, cacheKey, gradleHomeEntryListener)
|
await saveCache(cachePath, cacheKey, gradleHomeEntryListener)
|
||||||
|
core.info(
|
||||||
|
`Saved ${this.cacheDescription} with key ${cacheKey} from ${cachePath.join()} in ${gradleHomeEntryListener.savedTime}ms`
|
||||||
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import exp from 'constants'
|
||||||
import {CacheEntryListener, CacheListener} from '../../src/caching/cache-reporting'
|
import {CacheEntryListener, CacheListener} from '../../src/caching/cache-reporting'
|
||||||
|
|
||||||
describe('caching report', () => {
|
describe('caching report', () => {
|
||||||
@ -5,7 +6,7 @@ describe('caching report', () => {
|
|||||||
it('with one requested entry report', async () => {
|
it('with one requested entry report', async () => {
|
||||||
const report = new CacheListener()
|
const report = new CacheListener()
|
||||||
report.entry('foo').markRequested('1', ['2'])
|
report.entry('foo').markRequested('1', ['2'])
|
||||||
report.entry('bar').markRequested('3').markRestored('4', 500)
|
report.entry('bar').markRequested('3').markRestored('4', 500, 1000)
|
||||||
expect(report.fullyRestored).toBe(false)
|
expect(report.fullyRestored).toBe(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -22,13 +23,13 @@ describe('caching report', () => {
|
|||||||
})
|
})
|
||||||
it('with restored entry report', async () => {
|
it('with restored entry report', async () => {
|
||||||
const report = new CacheListener()
|
const report = new CacheListener()
|
||||||
report.entry('bar').markRequested('3').markRestored('4', 300)
|
report.entry('bar').markRequested('3').markRestored('4', 300, 1000)
|
||||||
expect(report.fullyRestored).toBe(true)
|
expect(report.fullyRestored).toBe(true)
|
||||||
})
|
})
|
||||||
it('with multiple restored entry reportss', async () => {
|
it('with multiple restored entry reportss', async () => {
|
||||||
const report = new CacheListener()
|
const report = new CacheListener()
|
||||||
report.entry('foo').markRestored('4', 3300)
|
report.entry('foo').markRestored('4', 3300, 111)
|
||||||
report.entry('bar').markRequested('3').markRestored('4', 333)
|
report.entry('bar').markRequested('3').markRestored('4', 333, 1000)
|
||||||
expect(report.fullyRestored).toBe(true)
|
expect(report.fullyRestored).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -64,7 +65,7 @@ describe('caching report', () => {
|
|||||||
const report = new CacheListener()
|
const report = new CacheListener()
|
||||||
const entryReport = report.entry('foo')
|
const entryReport = report.entry('foo')
|
||||||
entryReport.markRequested('1', ['2', '3'])
|
entryReport.markRequested('1', ['2', '3'])
|
||||||
entryReport.markSaved('4', 100)
|
entryReport.markSaved('4', 100, 1000)
|
||||||
|
|
||||||
const stringRep = report.stringify()
|
const stringRep = report.stringify()
|
||||||
const reportClone: CacheListener = CacheListener.rehydrate(stringRep)
|
const reportClone: CacheListener = CacheListener.rehydrate(stringRep)
|
||||||
@ -73,6 +74,8 @@ describe('caching report', () => {
|
|||||||
expect(entryClone.requestedKey).toBe('1')
|
expect(entryClone.requestedKey).toBe('1')
|
||||||
expect(entryClone.requestedRestoreKeys).toEqual(['2', '3'])
|
expect(entryClone.requestedRestoreKeys).toEqual(['2', '3'])
|
||||||
expect(entryClone.savedKey).toBe('4')
|
expect(entryClone.savedKey).toBe('4')
|
||||||
|
expect(entryClone.savedSize).toBe(100)
|
||||||
|
expect(entryClone.savedTime).toBe(1000)
|
||||||
})
|
})
|
||||||
it('with live entry report', async () => {
|
it('with live entry report', async () => {
|
||||||
const report = new CacheListener()
|
const report = new CacheListener()
|
||||||
@ -85,7 +88,7 @@ describe('caching report', () => {
|
|||||||
|
|
||||||
// Check type and call method on rehydrated entry report
|
// Check type and call method on rehydrated entry report
|
||||||
expect(entryClone).toBeInstanceOf(CacheEntryListener)
|
expect(entryClone).toBeInstanceOf(CacheEntryListener)
|
||||||
entryClone.markSaved('4', 100)
|
entryClone.markSaved('4', 100, 1000)
|
||||||
|
|
||||||
expect(entryClone.requestedKey).toBe('1')
|
expect(entryClone.requestedKey).toBe('1')
|
||||||
expect(entryClone.requestedRestoreKeys).toEqual(['2', '3'])
|
expect(entryClone.requestedRestoreKeys).toEqual(['2', '3'])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user