Skip to content

Commit 50f5a67

Browse files
committed
use native-promise-pool
1 parent acaa13b commit 50f5a67

File tree

6 files changed

+60
-4
lines changed

6 files changed

+60
-4
lines changed

action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ inputs:
1414
description: An ordered list of keys to use for restoring the cache if no cache hit occurred for key
1515
required: false
1616
default: docker-layer-caching-${{ github.workflow }}-
17+
concurrency:
18+
description: The number of concurrency when restoring and saving layers
19+
required: true
20+
default: '4'
1721

1822
runs:
1923
using: node12

main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const main = async () => {
1111
core.saveState(`already-existing-images`, JSON.stringify(await new ImageDetector().getExistingImages()))
1212

1313
const layerCache = new LayerCache([])
14+
layerCache.concurrency = parseInt(core.getInput(`concurrency`, { required: true }), 10)
1415
const restoredKey = await layerCache.restore(primaryKey, restoreKeys)
1516
await layerCache.cleanUp()
1617

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"@actions/core": "^1.2.4",
1111
"actions-exec-listener": "^0.0.2",
1212
"crypto": "^1.0.1",
13+
"native-promise-pool": "^3.13.0",
1314
"string-format": "^2.0.0",
1415
"typescript-is": "^0.16.3"
1516
},

post.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const main = async () => {
1818
await imageDetector.getExistingImages()
1919
core.debug(JSON.stringify({ imageIdsToSave: imageDetector.getImagesShouldSave() }))
2020
const layerCache = new LayerCache(imageDetector.getImagesShouldSave())
21+
layerCache.concurrency = parseInt(core.getInput(`concurrency`, { required: true }), 10)
2122

2223
layerCache.unformattedOrigianlKey = primaryKey
2324
core.debug(JSON.stringify({ restoredKey, formattedOriginalCacheKey: layerCache.getFormattedOriginalCacheKey()}))

src/LayerCache.ts

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@ import { ExecOptions } from '@actions/exec/lib/interfaces'
77
import { promises as fs } from 'fs'
88
import { assertManifests, Manifest, Manifests } from './Tar'
99
import format from 'string-format'
10+
import PromisePool from 'native-promise-pool'
11+
12+
type ReturnPromiseFunc = <T>(arg: any) => Promise<T[]>
13+
14+
const createPromiseProducerFromArray = <T, T2>(array: T[], callBackFunc: ((t: T) => Promise<T2>)) => {
15+
const currentIndex = 0;
16+
17+
return () => callBackFunc(array[currentIndex])
18+
}
19+
20+
const generatePromise = function * <T1, T2>(array: T1[], callbackFunc: ((t: T1) => Promise<T2>)) {
21+
for (let i = 0; i < array.length; i++) {
22+
yield callbackFunc(array[i])
23+
}
24+
}
1025

1126
class LayerCache {
1227
// repotag: string
@@ -18,6 +33,7 @@ class LayerCache {
1833
enabledParallel = true
1934
// unpackedTarDir: string = ''
2035
// manifests: Manifests = []
36+
concurrency: number = 4
2137

2238
constructor(ids: string[]) {
2339
// this.repotag = repotag
@@ -108,7 +124,16 @@ class LayerCache {
108124
}
109125

110126
private async storeLayers(): Promise<number[]> {
111-
return await Promise.all((await this.getLayerIds()).map(layerId => this.storeSingleLayerBy(layerId)))
127+
const pool = new PromisePool(this.concurrency)
128+
129+
const result = Promise.all(
130+
(await this.getLayerIds()).map(
131+
layerId => {
132+
return pool.open(() => this.storeSingleLayerBy(layerId))
133+
}
134+
)
135+
)
136+
return result
112137
}
113138

114139
static async dismissCacheAlreadyExistsError(promise: Promise<number>): Promise<number> {
@@ -174,15 +199,34 @@ class LayerCache {
174199

175200
private async restoreLayers() {
176201
const restoring = (await this.getLayerIds()).map(layerId => this.restoreSingleLayerBy(layerId));
177-
const restoredLayerKeysThatMayContainUndefined = await Promise.all(restoring)
202+
203+
const promiseIter = generatePromise(await this.getLayerIds(), layerId => this.restoreSingleLayerBy(layerId))
204+
205+
const pool = new PromisePool(this.concurrency)
206+
207+
const restoredLayerKeysThatMayContainUndefined = await Promise.all(
208+
(await this.getLayerIds()).map(
209+
layerId => {
210+
return pool.open(() => this.restoreSingleLayerBy(layerId))
211+
}
212+
)
213+
)
214+
178215
core.debug(JSON.stringify({ log: `restoreLayers`, restoredLayerKeysThatMayContainUndefined }))
179216
const FailedToRestore = (restored: string | undefined) => restored === undefined
180217
return restoredLayerKeysThatMayContainUndefined.filter(FailedToRestore).length === 0
181218
}
182219

183-
private async restoreSingleLayerBy(id: string): Promise<string | undefined> {
220+
private async restoreSingleLayerBy(id: string): Promise<string> {
184221
core.debug(JSON.stringify({ log: `restoreSingleLayerBy`, id }))
185-
return await cache.restoreCache([this.genSingleLayerStorePath(id)], this.genSingleLayerStoreKey(id))
222+
223+
const result = await cache.restoreCache([this.genSingleLayerStorePath(id)], this.genSingleLayerStoreKey(id))
224+
225+
if (result == null) {
226+
throw new Error(`Layer cache not found: ${JSON.stringify({ id })}`)
227+
}
228+
229+
return result
186230
}
187231

188232
private async loadImageFromUnpacked() {

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,11 @@ minimatch@^3.0.4:
329329
dependencies:
330330
brace-expansion "^1.1.7"
331331

332+
native-promise-pool@^3.13.0:
333+
version "3.13.0"
334+
resolved "https://registry.yarnpkg.com/native-promise-pool/-/native-promise-pool-3.13.0.tgz#faeaf9b4ee769a79328cc0435930079ad951b27b"
335+
integrity sha512-CnUhv57AXMyxGazhYrqhlhwRg1rG36ygrDlnaCa70jBOePhV+OLM9CZkUAgceTXO6BZEQ3F5GRRWwB+wSzI4Aw==
336+
332337
nested-error-stacks@^2:
333338
version "2.1.0"
334339
resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61"

0 commit comments

Comments
 (0)